vhost.c revision 3c290fd0361d6d9d84d97725eaf299456bddd6cf
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* Licensed to the Apache Software Foundation (ASF) under one or more
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * contributor license agreements. See the NOTICE file distributed with
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * this work for additional information regarding copyright ownership.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * The ASF licenses this file to You under the Apache License, Version 2.0
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * (the "License"); you may not use this file except in compliance with
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * the License. You may obtain a copy of the License at
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * http://www.apache.org/licenses/LICENSE-2.0
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Unless required by applicable law or agreed to in writing, software
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * distributed under the License is distributed on an "AS IS" BASIS,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * See the License for the specific language governing permissions and
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * limitations under the License.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/**
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * @file vhost.c
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * @brief functions pertaining to virtual host addresses
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * (configuration and run-time)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "apr.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "apr_strings.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "apr_lib.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#define APR_WANT_STRFUNC
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "apr_want.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "ap_config.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "httpd.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "http_config.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "http_log.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "http_vhost.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "http_protocol.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include "http_core.h"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#if APR_HAVE_ARPA_INET_H
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#include <arpa/inet.h>
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#endif
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* we know core's module_index is 0 */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#undef APLOG_MODULE_INDEX
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/*
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * After all the definitions there's an explanation of how it's all put
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * together.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * lists of name-vhosts.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmanntypedef struct name_chain name_chain;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstruct name_chain {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann name_chain *next;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec *sar; /* the record causing it to be in
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * this chain (needed for port comparisons) */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *server; /* the server to use on a match */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann};
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
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 */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmanntypedef struct ipaddr_chain ipaddr_chain;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstruct ipaddr_chain {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *next;
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 name_chain *initialnames; /* no runtime use, temporary storage of first
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * NVH'es names */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann};
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* This defines the size of the hash table used for hashing ip addresses
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * of virtual hosts. It must be a power of two.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#ifndef IPHASH_TABLE_SIZE
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann#define IPHASH_TABLE_SIZE 256
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#endif
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
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 *
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Note that after config time this is constant, so it is thread-safe.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* dump out statistics about the hash function */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* #define IPHASH_STATISTICS */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* list of the _default_ servers */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *default_list;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* whether a config error was seen */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic int config_error = 0;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* config check function */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_pool_t *ptemp, server_rec *s);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/*
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * How it's used:
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *
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 *
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *
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 *
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 *
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 */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* called at the beginning of the config */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel HoltmannAP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann memset(iphash_table, 0, sizeof(iphash_table));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann default_list = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/*
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 Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic const char *get_addresses(apr_pool_t *p, const char *w_,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec ***paddr,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_port_t default_port)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_sockaddr_t *my_addr;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec *sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann char *w, *host, *scope_id;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann int wild_port;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_size_t wlen;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_port_t port;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_status_t rv;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (*w_ == '\0')
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wlen = strlen(w_); /* wlen must be > 0 at this point */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann w = apr_pstrmemdup(p, w_, wlen);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wild_port = 0;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (w[wlen - 1] == '*') {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (wlen < 2) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wild_port = 1;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else if (w[wlen - 2] == ':') {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann w[wlen - 2] = '\0';
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wild_port = 1;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* If the string is "80", apr_parse_addr_port() will be happy and set
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * host to NULL and port to 80, so watch out for that.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (rv != APR_SUCCESS) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "The address or port is invalid";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (!host) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "Missing address for VirtualHost";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (scope_id) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "Scope ids are not supported";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (!port && !wild_port) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann port = default_port;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (rv) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "Could not resolve address '0.0.0.0' -- "
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "check resolver configuration.";
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (rv != APR_SUCCESS) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "Could not resolve host name %s -- ignoring!", host);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* Remember all addresses for the host */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann do {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar = apr_pcalloc(p, sizeof(server_addr_rec));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann **paddr = sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *paddr = &sar->next;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar->host_addr = my_addr;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar->host_port = port;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar->virthost = host;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann my_addr = my_addr->next;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann } while (my_addr);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* parse the <VirtualHost> addresses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannconst char *ap_parse_vhost_addrs(apr_pool_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann const char *hostname,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *s)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec **addrs;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann const char *err;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* start the list of addreses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann addrs = &s->addrs;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann while (hostname[0]) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (err) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *addrs = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return err;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* terminate the list */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann *addrs = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (s->addrs) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (s->addrs->host_port) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* override the default port which is inherited from main_server */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann s->port = s->addrs->host_port;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel HoltmannAP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann void *dummy,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann const char *arg)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann static int warnonce = 0;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (++warnonce == 1) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_NOTICE|APLOG_STARTUP, APR_SUCCESS, NULL,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "NameVirtualHost has no effect and will be removed in the "
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "next release %s:%d",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann cmd->directive->filename,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann cmd->directive->line_num);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* hash table statistics, keep this in here for the beta period so
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * we can find out if the hash function is ok
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#ifdef IPHASH_STATISTICS
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic int iphash_compare(const void *a, const void *b)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return (*(const int *) b - *(const int *) a);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void dump_iphash_statistics(server_rec *main_s)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann unsigned count[IPHASH_TABLE_SIZE];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann int i;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *src;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann unsigned total;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann char buf[HUGE_STRING_LEN];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann char *p;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann total = 0;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann count[i] = 0;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (src = iphash_table[i]; src; src = src->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ++count[i];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (i < IPHASH_TABLE_SIZE) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't count the slop buckets in the total */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ++total;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p = buf + apr_snprintf(buf, sizeof(buf),
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "iphash: total hashed = %u, avg chain = %u, "
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "chain lengths (count x len):",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann total, total / IPHASH_TABLE_SIZE);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann total = 1;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (count[i - 1] != count[i]) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann total, count[i - 1]);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann total = 1;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ++total;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann total, count[IPHASH_TABLE_SIZE - 1]);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#endif
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
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 *
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 *
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Hash function provided by David Hankins.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic APR_INLINE unsigned hash_inaddr(unsigned key)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann key ^= (key >> 16);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann unsigned key;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* The key is the last four bytes of the IP address.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * For IPv4, this is the entire address, as always.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * For IPv6, this is usually part of the MAC address.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return hash_inaddr(key);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *s, server_addr_rec *sar)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *new;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new = apr_palloc(p, sizeof(*new));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->names = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->initialnames = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->server = s;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->sar = sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->next = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return new;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic name_chain *new_name_chain(apr_pool_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *s, server_addr_rec *sar)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann name_chain *new;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann new = apr_palloc(p, sizeof(*new));
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann new->server = s;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->sar = sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann new->next = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return new;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann unsigned bucket;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *trav = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *wild_match = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* scan the hash table for an exact match first */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann bucket = hash_addr(sa);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (trav = iphash_table[bucket]; trav; trav = trav->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec *sar = trav->sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_sockaddr_t *cur = sar->host_addr;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (cur->port == sa->port) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (apr_sockaddr_equal(cur, sa)) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return trav;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (apr_sockaddr_equal(cur, sa)) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't break, continue looking for an exact match */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wild_match = trav;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return wild_match;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *find_default_server(apr_port_t port)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec *sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *trav = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *wild_match = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (trav = default_list; trav; trav = trav->next) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann sar = trav->sar;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (sar->host_port == port) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* match! */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return trav;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (wild_match == NULL && sar->host_port == 0) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't break, continue looking for an exact match */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wild_match = trav;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return wild_match;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann name_chain *nc;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann int len;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann char buf[MAX_STRING_LEN];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_sockaddr_t *ha = ic->sar->host_addr;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (ha->family == APR_INET &&
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ha->sa.sin.sin_addr.s_addr == INADDR_ANY) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann len = apr_snprintf(buf, sizeof(buf), "*:%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (ic->sar->host_port == 0) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann buf[len-1] = '*';
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (ic->names == NULL) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic->server->server_hostname,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server->defn_name, ic->server->defn_line_number);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%-22s is a NameVirtualHost\n"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "%8s default server %s (%s:%u)\n",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann buf, "", ic->server->server_hostname,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server->defn_name, ic->server->defn_line_number);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (nc = ic->names; nc; nc = nc->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (nc->sar->host_port) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%8s port * ", "");
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "namevhost %s (%s:%u)\n",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann nc->server->server_hostname,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann nc->server->defn_name, nc->server->defn_line_number);
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (nc->server->names) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_array_header_t *names = nc->server->names;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann char **name = (char **)names->elts;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann int i;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < names->nelts; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (name[i]) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%16s alias %s\n", "", name[i]);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (nc->server->wild_names) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_array_header_t *names = nc->server->wild_names;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann char **name = (char **)names->elts;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann int i;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < names->nelts; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (name[i]) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void dump_vhost_config(apr_file_t *f)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *ic;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann int i;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "VirtualHost configuration:\n");
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* non-wildcard servers */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (ic = iphash_table[i]; ic; ic = ic->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann dump_a_vhost(f, ic);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* wildcard servers */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (ic = default_list; ic; ic = ic->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann dump_a_vhost(f, ic);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/*
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * When a second or later virtual host maps to the same IP chain,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * add the relevant server names to the chain. Special care is taken
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * to avoid adding ic->names until we're sure there are multiple VH'es.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *s, server_addr_rec *sar,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ipaddr_chain *ic)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann{
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann name_chain *nc = new_name_chain(p, s, sar);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann nc->next = ic->names;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* iterating backwards, so each one we see becomes the current default server */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server = s;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (ic->names == NULL) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (ic->initialnames == NULL) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* first pass, set these names aside in case we see another VH.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Until then, this looks like an IP-based VH to runtime.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->initialnames = nc;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* second pass through this chain -- this really is an NVH, and we
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * have two sets of names to link in.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann nc->next = ic->initialnames;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->names = nc;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->initialnames = NULL;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann else {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* 3rd or more -- just keep stacking the names */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->names = nc;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann }
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann}
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/* compile the tables and such we need to do the run-time vhost lookups */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel HoltmannAP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann{
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann server_addr_rec *sar;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann int has_default_vhost_addr;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann server_rec *s;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann int i;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* Main host first */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s = main_s;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!s->server_hostname) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = ap_get_local_host(p);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* initialize the tails */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann iphash_table_tail[i] = &iphash_table[i];
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* The next things to go into the hash table are the virtual hosts
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * themselves. They're listed off of main_s->next in the reverse
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * order they occured in the config file, so we insert them at
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * the iphash_table_tail but don't advance the tail.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (s = main_s->next; s; s = s->next) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann has_default_vhost_addr = 0;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (sar = s->addrs; sar; sar = sar->next) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ipaddr_chain *ic;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic = find_default_server(sar->host_port);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!ic || sar->host_port != ic->sar->host_port) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* No default server, or we found a default server but
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ** exactly one of us is a wildcard port, which means we want
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ** two ip-based vhosts not an NVH with two names
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic = new_ipaddr_chain(p, s, sar);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic->next = default_list;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann default_list = ic;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann has_default_vhost_addr = 1;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann else {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* see if it matches something we've already got */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic = find_ipaddr(sar->host_addr);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!ic || sar->host_port != ic->sar->host_port) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* No matching server, or we found a matching server but
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ** exactly one of us is a wildcard port, which means we want
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ** two ip-based vhosts not an NVH with two names
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann unsigned bucket = hash_addr(sar->host_addr);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic = new_ipaddr_chain(p, s, sar);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ic->next = *iphash_table_tail[bucket];
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann *iphash_table_tail[bucket] = ic;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann add_name_vhost_config(p, main_s, s, sar, ic);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
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 */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!s->server_hostname) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (has_default_vhost_addr) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = main_s->server_hostname;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
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 s->server_hostname =
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_pstrdup(p, "bogus_host_without_forward_dns");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann else {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_status_t rv;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char *hostname;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (rv == APR_SUCCESS) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = apr_pstrdup(p, hostname);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann else {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* again, what can we do? They didn't specify a
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ServerName, and their DNS isn't working. -djg */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char *ipaddr_str;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann "Failed to resolve server name "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "for %s (check DNS) -- or specify an explicit "
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "ServerName",
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ipaddr_str);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname =
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_pstrdup(p, "bogus_host_without_reverse_dns");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann#ifdef IPHASH_STATISTICS
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann dump_iphash_statistics(main_s);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann#endif
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (ap_exists_config_define("DUMP_VHOSTS")) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_file_t *thefile = NULL;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_file_open_stdout(&thefile, p);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann dump_vhost_config(thefile);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann}
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmannstatic int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_pool_t *ptemp, server_rec *s)
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann{
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann return config_error ? !OK : OK;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann}
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/*****************************************************************************
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * run-time vhost matching functions
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/* Lowercase and remove any trailing dot and/or :port from the hostname,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * and check that it is sane.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann *
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * In most configurations the exact syntax of the hostname isn't
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * important so strict sanity checking isn't necessary. However, in
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * the hostname is interpolated into the filename, we need to be sure
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * that the interpolation doesn't expose parts of the filesystem.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * We don't do strict RFC 952 / RFC 1123 syntax checking in order
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * to support iDNS and people who erroneously use underscores.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * Instead we just check for filesystem metacharacters: directory
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * separators / and \ and sequences of more than one dot.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmannstatic void fix_hostname(request_rec *r)
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann{
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char *host, *scope_id;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char *dst;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_port_t port;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_status_t rv;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann const char *c;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* According to RFC 2616, Host header field CAN be blank. */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!*r->hostname) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann return;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* apr_parse_addr_port will interpret a bare integer as a port
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * which is incorrect in this context. So treat it separately.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (c = r->hostname; apr_isdigit(*c); ++c);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!*c) { /* pure integer */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann return;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (rv != APR_SUCCESS || scope_id) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann goto bad;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (port) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* Don't throw the Host: header's port number away:
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann save it in parsed_uri -- ap_get_server_port() needs it! */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* @@@ XXX there should be a better way to pass the port.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * Like r->hostname, there should be a r->portno
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann r->parsed_uri.port = port;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann }
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* if the hostname is an IPv6 numeric address string, it was validated
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * already; otherwise, further validation is needed
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (r->hostname[0] != '[') {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (dst = host; *dst; dst++) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (apr_islower(*dst)) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* leave char unchanged */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann else if (*dst == '.') {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (*(dst + 1) == '.') {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann goto bad;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann else if (apr_isupper(*dst)) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann *dst = apr_tolower(*dst);
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann else if (*dst == '/' || *dst == '\\') {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann goto bad;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* strip trailing gubbins */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (dst > host && dst[-1] == '.') {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann dst[-1] = '\0';
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann r->hostname = host;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann return;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmannbad:
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann r->status = HTTP_BAD_REQUEST;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann "Client sent malformed Host header");
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann return;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann}
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann/* return 1 if host matches ServerName or ServerAliases */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmannstatic int matches_aliases(server_rec *s, const char *host)
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann{
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann int i;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann apr_array_header_t *names;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* match ServerName */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (!strcasecmp(host, s->server_hostname)) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann return 1;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* search all the aliases from ServerAlias directive */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann names = s->names;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (names) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann char **name = (char **) names->elts;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (i = 0; i < names->nelts; ++i) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if(!name[i]) continue;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (!strcasecmp(host, name[i]))
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann return 1;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann names = s->wild_names;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (names) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann char **name = (char **) names->elts;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (i = 0; i < names->nelts; ++i) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if(!name[i]) continue;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (!ap_strcasecmp_match(host, name[i]))
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann return 1;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann }
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann return 0;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann}
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
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 Holtmann */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel HoltmannAP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann apr_port_t port)
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann{
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann server_rec *s;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann server_addr_rec *sar;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann s = r->server;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann
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 * consider:
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann *
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 *
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 */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (sar = s->addrs; sar; sar = sar->next) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if ((sar->host_port == 0 || port == sar->host_port)
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann && !strcasecmp(host, sar->virthost)) {
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann return 1;
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann }
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann }
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann /* the Port has to match now, because the rest don't have ports associated
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann * with them. */
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann if (port != s->port) {
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann return 0;
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann }
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann return matches_aliases(s, host);
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann}
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmannstatic void check_hostalias(request_rec *r)
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann{
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann /*
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann * Even if the request has a Host: header containing a port we ignore
* that port. We always use the physical port of the socket. There
* are a few reasons for this:
*
* - the default of 80 or 443 for SSL is easier to handle this way
* - there is less of a possibility of a security problem
* - it simplifies the data structure
* - the client may have no idea that a proxy somewhere along the way
* translated the request to another ip:port
* - except for the addresses from the VirtualHost line, none of the other
* names we'll match have ports associated with them
*/
const char *host = r->hostname;
apr_port_t port;
server_rec *s;
server_rec *last_s;
name_chain *src;
last_s = NULL;
port = r->connection->local_addr->port;
/* Recall that the name_chain is a list of server_addr_recs, some of
* whose ports may not match. Also each server may appear more than
* once in the chain -- specifically, it will appear once for each
* address from its VirtualHost line which matched. We only want to
* do the full ServerName/ServerAlias comparisons once for each
* server, fortunately we know that all the VirtualHost addresses for
* a single server are adjacent to each other.
*/
for (src = r->connection->vhost_lookup_data; src; src = src->next) {
server_addr_rec *sar;
/* We only consider addresses on the name_chain which have a matching
* port
*/
sar = src->sar;
if (sar->host_port != 0 && port != sar->host_port) {
continue;
}
s = src->server;
/* does it match the virthost from the sar? */
if (!strcasecmp(host, sar->virthost)) {
goto found;
}
if (s == last_s) {
/* we've already done ServerName and ServerAlias checks for this
* vhost
*/
continue;
}
last_s = s;
if (matches_aliases(s, host)) {
goto found;
}
}
return;
found:
/* s is the first matching server, we're done */
r->server = s;
}
static void check_serverpath(request_rec *r)
{
server_rec *s;
server_rec *last_s;
name_chain *src;
apr_port_t port;
port = r->connection->local_addr->port;
/*
* This is in conjunction with the ServerPath code in http_core, so we
* get the right host attached to a non- Host-sending request.
*
* See the comment in check_hostalias about how each vhost can be
* listed multiple times.
*/
last_s = NULL;
for (src = r->connection->vhost_lookup_data; src; src = src->next) {
/* We only consider addresses on the name_chain which have a matching
* port
*/
if (src->sar->host_port != 0 && port != src->sar->host_port) {
continue;
}
s = src->server;
if (s == last_s) {
continue;
}
last_s = s;
if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
(s->path[s->pathlen - 1] == '/' ||
r->uri[s->pathlen] == '/' ||
r->uri[s->pathlen] == '\0')) {
r->server = s;
return;
}
}
}
AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
{
/* must set this for HTTP/1.1 support */
if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
fix_hostname(r);
if (r->status != HTTP_OK)
return;
}
/* check if we tucked away a name_chain */
if (r->connection->vhost_lookup_data) {
if (r->hostname)
check_hostalias(r);
else
check_serverpath(r);
}
}
/**
* For every virtual host on this connection, call func_cb.
*/
AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
ap_vhost_iterate_conn_cb func_cb,
void* baton)
{
server_rec *s;
server_rec *last_s;
name_chain *src;
apr_port_t port;
int rv = 0;
if (conn->vhost_lookup_data) {
last_s = NULL;
port = conn->local_addr->port;
for (src = conn->vhost_lookup_data; src; src = src->next) {
server_addr_rec *sar;
/* We only consider addresses on the name_chain which have a
* matching port.
*/
sar = src->sar;
if (sar->host_port != 0 && port != sar->host_port) {
continue;
}
s = src->server;
if (s == last_s) {
/* we've already done a callback for this vhost. */
continue;
}
last_s = s;
rv = func_cb(baton, conn, s);
if (rv != 0) {
break;
}
}
}
else {
rv = func_cb(baton, conn, conn->base_server);
}
return rv;
}
/* Called for a new connection which has a known local_addr. Note that the
* new connection is assumed to have conn->server == main server.
*/
AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
{
ipaddr_chain *trav;
apr_port_t port;
/* scan the hash table for an exact match first */
trav = find_ipaddr(conn->local_addr);
if (trav) {
/* save the name_chain for later in case this is a name-vhost */
conn->vhost_lookup_data = trav->names;
conn->base_server = trav->server;
return;
}
/* maybe there's a default server or wildcard name-based vhost
* matching this port
*/
port = conn->local_addr->port;
trav = find_default_server(port);
if (trav) {
conn->vhost_lookup_data = trav->names;
conn->base_server = trav->server;
return;
}
/* otherwise we're stuck with just the main server
* and no name-based vhosts
*/
conn->vhost_lookup_data = NULL;
}