vhost.c revision 7697b1b7376a532163c621e050b70c90dcb15d66
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek/* Licensed to the Apache Software Foundation (ASF) under one or more
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * contributor license agreements. See the NOTICE file distributed with
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * this work for additional information regarding copyright ownership.
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * The ASF licenses this file to You under the Apache License, Version 2.0
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * (the "License"); you may not use this file except in compliance with
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * the License. You may obtain a copy of the License at
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek *
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * http://www.apache.org/licenses/LICENSE-2.0
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek *
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * Unless required by applicable law or agreed to in writing, software
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * distributed under the License is distributed on an "AS IS" BASIS,
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * See the License for the specific language governing permissions and
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * limitations under the License.
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek */
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek/**
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * @file vhost.c
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * @brief functions pertaining to virtual host addresses
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek * (configuration and run-time)
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek */
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek#include "apr.h"
21ac6ff143cc8bebfbd1818af28e8c6f82cd5265Zbigniew Jędrzejewski-Szmek#include "apr_strings.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_lib.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define APR_WANT_STRFUNC
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_want.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "ap_config.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "httpd.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_config.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_log.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_vhost.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_protocol.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_core.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#if APR_HAVE_ARPA_INET_H
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include <arpa/inet.h>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#endif
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAPLOG_USE_MODULE(core);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * After all the definitions there's an explanation of how it's all put
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * together.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * lists of name-vhosts.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmektypedef struct name_chain name_chain;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstruct name_chain {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *next;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_addr_rec *sar; /* the record causing it to be in
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * this chain (needed for port comparisons) */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *server; /* the server to use on a match */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek};
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* meta-list of ip addresses. Each server_rec can be in possibly multiple
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * hash chains since it can have multiple ips.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmektypedef struct ipaddr_chain ipaddr_chain;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstruct ipaddr_chain {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *next;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_addr_rec *sar; /* the record causing it to be in
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * this chain (need for both ip addr and port
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * comparisons) */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *server; /* the server to use if this matches */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *names; /* if non-NULL then a list of name-vhosts
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * sharing this address */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *initialnames; /* no runtime use, temporary storage of first
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * NVH'es names */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek};
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* This defines the size of the hash table used for hashing ip addresses
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * of virtual hosts. It must be a power of two.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#ifndef IPHASH_TABLE_SIZE
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define IPHASH_TABLE_SIZE 256
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#endif
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* A (n) bucket hash table, each entry has a pointer to a server rec and
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * a pointer to the other entries in that bucket. Each individual address,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * even for virtualhosts with multiple addresses, has an entry in this hash
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * table. There are extra buckets for _default_, and name-vhost entries.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Note that after config time this is constant, so it is thread-safe.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* dump out statistics about the hash function */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* #define IPHASH_STATISTICS */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* list of the _default_ servers */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ipaddr_chain *default_list;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* whether a config error was seen */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int config_error = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* config check function */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_pool_t *ptemp, server_rec *s);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * How it's used:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * The ip address determines which chain in iphash_table is interesting, then
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * a comparison is done down that chain to find the first ipaddr_chain whose
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * sar matches the address:port pair.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Otherwise it's a name-vhost list, and the default is the server in the
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ipaddr_chain record. We tuck away the ipaddr_chain record in the
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * conn_rec field vhost_lookup_data. Later on after the headers we get a
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * second chance, and we use the name_chain to figure out what name-vhost
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * matches the headers.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * If there was no ip address match in the iphash_table then do a lookup
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * in the default_list.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * How it's put together ... well you should be able to figure that out
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * from how it's used. Or something like that.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* called at the beginning of the config */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek memset(iphash_table, 0, sizeof(iphash_table));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek default_list = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Parses a host of the form <address>[:port]
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * paddr is used to create a list in the order of input
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * **paddr is the ->next pointer of the last entry (or s->addrs)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * *paddr is the variable used to keep track of **paddr between calls
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * port is the default port to assume
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic const char *get_addresses(apr_pool_t *p, const char *w_,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_addr_rec ***paddr,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_port_t default_port)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_sockaddr_t *my_addr;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_addr_rec *sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *w, *host, *scope_id;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int wild_port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_size_t wlen;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_port_t port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_status_t rv;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (*w_ == '\0')
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek w = apr_pstrdup(p, w_);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek wlen = strlen(w); /* wlen must be > 0 at this point */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek wild_port = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (w[wlen - 1] == '*') {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (wlen < 2) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek wild_port = 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else if (w[wlen - 2] == ':') {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek w[wlen - 2] = '\0';
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek wild_port = 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* If the string is "80", apr_parse_addr_port() will be happy and set
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * host to NULL and port to 80, so watch out for that.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (rv != APR_SUCCESS) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return "The address or port is invalid";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!host) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return "Missing address for VirtualHost";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (scope_id) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return "Scope ids are not supported";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!port && !wild_port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek port = default_port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (rv) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return "Could not resolve address '0.0.0.0' -- "
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "check resolver configuration.";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (rv != APR_SUCCESS) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "Could not resolve host name %s -- ignoring!", host);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Remember all addresses for the host */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek do {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sar = apr_pcalloc(p, sizeof(server_addr_rec));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek **paddr = sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *paddr = &sar->next;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sar->host_addr = my_addr;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sar->host_port = port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sar->virthost = host;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek my_addr = my_addr->next;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } while (my_addr);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering return NULL;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering}
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering/* parse the <VirtualHost> addresses */
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poetteringconst char *ap_parse_vhost_addrs(apr_pool_t *p,
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering const char *hostname,
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering server_rec *s)
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering{
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering server_addr_rec **addrs;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering const char *err;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* start the list of addreses */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek addrs = &s->addrs;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek while (hostname[0]) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (err) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *addrs = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return err;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* terminate the list */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *addrs = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (s->addrs) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (s->addrs->host_port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* override the default port which is inherited from main_server */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s->port = s->addrs->host_port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekAP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek void *dummy,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *arg)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek static int warnonce = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (++warnonce == 1) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_NOTICE|APLOG_STARTUP, APR_SUCCESS, NULL,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "NameVirtualHost has no effect and will be removed in the "
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "next release %s:%d",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek cmd->directive->filename,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek cmd->directive->line_num);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* hash table statistics, keep this in here for the beta period so
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * we can find out if the hash function is ok
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#ifdef IPHASH_STATISTICS
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int iphash_compare(const void *a, const void *b)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return (*(const int *) b - *(const int *) a);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void dump_iphash_statistics(server_rec *main_s)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned count[IPHASH_TABLE_SIZE];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *src;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned total;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char buf[HUGE_STRING_LEN];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *p;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek total = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek count[i] = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (src = iphash_table[i]; src; src = src->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ++count[i];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (i < IPHASH_TABLE_SIZE) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* don't count the slop buckets in the total */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ++total;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek p = buf + apr_snprintf(buf, sizeof(buf),
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "iphash: total hashed = %u, avg chain = %u, "
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "chain lengths (count x len):",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek total, total / IPHASH_TABLE_SIZE);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek total = 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (count[i - 1] != count[i]) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek total, count[i - 1]);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek total = 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ++total;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek total, count[IPHASH_TABLE_SIZE - 1]);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#endif
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* This hashing function is designed to get good distribution in the cases
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * where the server is handling entire "networks" of servers. i.e. a
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * whack of /24s. This is probably the most common configuration for
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ISPs with large virtual servers.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * NOTE: This function is symmetric (i.e. collapses all 4 octets
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * into one), so machine byte order (big/little endianness) does not matter.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Hash function provided by David Hankins.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic APR_INLINE unsigned hash_inaddr(unsigned key)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek key ^= (key >> 16);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned key;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* The key is the last four bytes of the IP address.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * For IPv4, this is the entire address, as always.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * For IPv6, this is usually part of the MAC address.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return hash_inaddr(key);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *s, server_addr_rec *sar)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *new;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new = apr_palloc(p, sizeof(*new));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->names = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->initialnames = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->server = s;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->sar = sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->next = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return new;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic name_chain *new_name_chain(apr_pool_t *p,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *s, server_addr_rec *sar)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *new;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new = apr_palloc(p, sizeof(*new));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->server = s;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->sar = sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek new->next = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return new;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned bucket;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *trav;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* scan the hash table for an exact match first */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek bucket = hash_addr(sa);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (trav = iphash_table[bucket]; trav; trav = trav->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_addr_rec *sar = trav->sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_sockaddr_t *cur = sar->host_addr;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (cur->port == 0 || sa->port == 0 || cur->port == sa->port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (apr_sockaddr_equal(cur, sa)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return trav;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ipaddr_chain *find_default_server(apr_port_t port)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_addr_rec *sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *trav;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (trav = default_list; trav; trav = trav->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sar = trav->sar;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (sar->host_port == 0 || sar->host_port == port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* match! */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return trav;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *nc;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int len;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char buf[MAX_STRING_LEN];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_sockaddr_t *ha = ic->sar->host_addr;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (ha->family == APR_INET &&
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ha->sa.sin.sin_addr.s_addr == INADDR_ANY) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek len = apr_snprintf(buf, sizeof(buf), "*:%u",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->sar->host_port);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (ic->sar->host_port == 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek buf[len-1] = '*';
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (ic->names == NULL) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->server->server_hostname,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->server->defn_name, ic->server->defn_line_number);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "%-22s is a NameVirtualHost\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "%8s default server %s (%s:%u)\n",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek buf, "", ic->server->server_hostname,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->server->defn_name, ic->server->defn_line_number);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (nc = ic->names; nc; nc = nc->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (nc->sar->host_port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "%8s port * ", "");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "namevhost %s (%s:%u)\n",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek nc->server->server_hostname,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek nc->server->defn_name, nc->server->defn_line_number);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (nc->server->names) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_array_header_t *names = nc->server->names;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char **name = (char **)names->elts;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < names->nelts; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (name[i]) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "%16s alias %s\n", "", name[i]);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (nc->server->wild_names) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_array_header_t *names = nc->server->wild_names;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char **name = (char **)names->elts;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < names->nelts; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (name[i]) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void dump_vhost_config(apr_file_t *f)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *ic;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek int i;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_printf(f, "VirtualHost configuration:\n");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* non-wildcard servers */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (ic = iphash_table[i]; ic; ic = ic->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek dump_a_vhost(f, ic);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* wildcard servers */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (ic = default_list; ic; ic = ic->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek dump_a_vhost(f, ic);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * When a second or later virtual host maps to the same IP chain,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * add the relevant server names to the chain. Special care is taken
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering * to avoid adding ic->names until we're sure there are multiple VH'es.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *s, server_addr_rec *sar,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *ic)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *nc = new_name_chain(p, s, sar);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering nc->next = ic->names;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* iterating backwards, so each one we see becomes the current default server */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->server = s;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (ic->names == NULL) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (ic->initialnames == NULL) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* first pass, set these names aside in case we see another VH.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Until then, this looks like an IP-based VH to runtime.
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->initialnames = nc;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* second pass through this chain -- this really is an NVH, and we
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * have two sets of names to link in.
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering */
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering nc->next = ic->initialnames;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering ic->names = nc;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering ic->initialnames = NULL;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering }
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering }
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering else {
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering /* 3rd or more -- just keep stacking the names */
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering ic->names = nc;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering }
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering}
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering/* compile the tables and such we need to do the run-time vhost lookups */
7de304525deafe4eb86060321e39787138dbbadfLennart PoetteringAP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering{
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering server_addr_rec *sar;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering int has_default_vhost_addr;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering server_rec *s;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering int i;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering /* Main host first */
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering s = main_s;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering if (!s->server_hostname) {
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering s->server_hostname = ap_get_local_host(p);
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering }
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering /* initialize the tails */
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering iphash_table_tail[i] = &iphash_table[i];
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* The next things to go into the hash table are the virtual hosts
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * themselves. They're listed off of main_s->next in the reverse
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * order they occured in the config file, so we insert them at
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * the iphash_table_tail but don't advance the tail.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (s = main_s->next; s; s = s->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek has_default_vhost_addr = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (sar = s->addrs; sar; sar = sar->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_chain *ic;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic = find_default_server(sar->host_port);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!ic || sar->host_port != ic->sar->host_port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* No default server, or we found a default server but
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ** exactly one of us is a wildcard port, which means we want
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ** two ip-based vhosts not an NVH with two names
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic = new_ipaddr_chain(p, s, sar);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->next = default_list;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek default_list = ic;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek has_default_vhost_addr = 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* see if it matches something we've already got */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic = find_ipaddr(sar->host_addr);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!ic || sar->host_port != ic->sar->host_port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* No matching server, or we found a matching server but
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ** exactly one of us is a wildcard port, which means we want
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ** two ip-based vhosts not an NVH with two names
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek unsigned bucket = hash_addr(sar->host_addr);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic = new_ipaddr_chain(p, s, sar);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ic->next = *iphash_table_tail[bucket];
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *iphash_table_tail[bucket] = ic;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek add_name_vhost_config(p, main_s, s, sar, ic);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Ok now we want to set up a server_hostname if the user was
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * silly enough to forget one.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * XXX: This is silly we should just crash and burn.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!s->server_hostname) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (has_default_vhost_addr) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s->server_hostname = main_s->server_hostname;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else if (!s->addrs) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* what else can we do? at this point this vhost has
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek no configured name, probably because they used
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek DNS in the VirtualHost statement. It's disabled
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek anyhow by the host matching code. -djg */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s->server_hostname =
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_pstrdup(p, "bogus_host_without_forward_dns");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_status_t rv;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *hostname;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (rv == APR_SUCCESS) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s->server_hostname = apr_pstrdup(p, hostname);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* again, what can we do? They didn't specify a
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ServerName, and their DNS isn't working. -djg */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *ipaddr_str;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "Failed to resolve server name "
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "for %s (check DNS) -- or specify an explicit "
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "ServerName",
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ipaddr_str);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s->server_hostname =
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_pstrdup(p, "bogus_host_without_reverse_dns");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#ifdef IPHASH_STATISTICS
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek dump_iphash_statistics(main_s);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#endif
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (ap_exists_config_define("DUMP_VHOSTS")) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_t *thefile = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_file_open_stdout(&thefile, p);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek dump_vhost_config(thefile);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_pool_t *ptemp, server_rec *s)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return config_error ? !OK : OK;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*****************************************************************************
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * run-time vhost matching functions
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* Lowercase and remove any trailing dot and/or :port from the hostname,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * and check that it is sane.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * In most configurations the exact syntax of the hostname isn't
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * important so strict sanity checking isn't necessary. However, in
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * the hostname is interpolated into the filename, we need to be sure
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * that the interpolation doesn't expose parts of the filesystem.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * We don't do strict RFC 952 / RFC 1123 syntax checking in order
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * to support iDNS and people who erroneously use underscores.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Instead we just check for filesystem metacharacters: directory
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * separators / and \ and sequences of more than one dot.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void fix_hostname(request_rec *r)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *host, *scope_id;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char *dst;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_port_t port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_status_t rv;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *c;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* According to RFC 2616, Host header field CAN be blank. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!*r->hostname) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* apr_parse_addr_port will interpret a bare integer as a port
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering * which is incorrect in this context. So treat it separately.
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering */
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering for (c = r->hostname; apr_isdigit(*c); ++c);
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering if (!*c) { /* pure integer */
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering return;
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering }
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering if (rv != APR_SUCCESS || scope_id) {
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering goto bad;
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering }
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering if (port) {
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering /* Don't throw the Host: header's port number away:
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering save it in parsed_uri -- ap_get_server_port() needs it! */
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering /* @@@ XXX there should be a better way to pass the port.
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering * Like r->hostname, there should be a r->portno
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering */
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering r->parsed_uri.port = port;
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering }
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering /* if the hostname is an IPv6 numeric address string, it was validated
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering * already; otherwise, further validation is needed
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering */
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering if (r->hostname[0] != '[') {
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering for (dst = host; *dst; dst++) {
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering if (apr_islower(*dst)) {
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering /* leave char unchanged */
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering }
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering else if (*dst == '.') {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering if (*(dst + 1) == '.') {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering goto bad;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering else if (apr_isupper(*dst)) {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering *dst = apr_tolower(*dst);
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering else if (*dst == '/' || *dst == '\\') {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering goto bad;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering /* strip trailing gubbins */
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering if (dst > host && dst[-1] == '.') {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering dst[-1] = '\0';
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering r->hostname = host;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering return;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poetteringbad:
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering r->status = HTTP_BAD_REQUEST;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering "Client sent malformed Host header");
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering return;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering}
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/* return 1 if host matches ServerName or ServerAliases */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int matches_aliases(server_rec *s, const char *host)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering int i;
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering apr_array_header_t *names;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* match ServerName */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!strcasecmp(host, s->server_hostname)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering /* search all the aliases from ServerAlias directive */
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering names = s->names;
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering if (names) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char **name = (char **) names->elts;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < names->nelts; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if(!name[i]) continue;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!strcasecmp(host, name[i]))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek names = s->wild_names;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (names) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char **name = (char **) names->elts;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < names->nelts; ++i) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if(!name[i]) continue;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!ap_strcasecmp_match(host, name[i]))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering/* Suppose a request came in on the same socket as this r, and included
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering * a header "Host: host:port", would it map to r->server? It's more
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering * than just that though. When we do the normal matches for each request
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering * we don't even bother considering Host: etc on non-namevirtualhosts,
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering * we just call it a match. But here we require the host:port to match
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering * the ServerName and/or ServerAliases.
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering */
7de304525deafe4eb86060321e39787138dbbadfLennart PoetteringAP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering apr_port_t port)
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering{
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering server_rec *s;
af40e5d3acbdcff09c8809cd1b86ecf8871f65f0Lennart Poettering server_addr_rec *sar;
7de304525deafe4eb86060321e39787138dbbadfLennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s = r->server;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* search all the <VirtualHost> values */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * consider:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * NameVirtualHost 10.1.1.1
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * <VirtualHost 10.1.1.1>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ServerName v1
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * </VirtualHost>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * <VirtualHost 10.1.1.1>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * ServerName v2
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * </VirtualHost>
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * it would really go to v1.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (sar = s->addrs; sar; sar = sar->next) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if ((sar->host_port == 0 || port == sar->host_port)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek && !strcasecmp(host, sar->virthost)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* the Port has to match now, because the rest don't have ports associated
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * with them. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (port != s->port) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return matches_aliases(s, host);
e0ea94c1e2ab3930c85c6057189a2a829a13a800Lennart Poettering}
e0ea94c1e2ab3930c85c6057189a2a829a13a800Lennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void check_hostalias(request_rec *r)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Even if the request has a Host: header containing a port we ignore
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * that port. We always use the physical port of the socket. There
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * are a few reasons for this:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * - the default of 80 or 443 for SSL is easier to handle this way
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * - there is less of a possibility of a security problem
ac92ced5bb41def1d90f871d6c8cfec2b03c0c7dBenjamin Franzke * - it simplifies the data structure
ac92ced5bb41def1d90f871d6c8cfec2b03c0c7dBenjamin Franzke * - the client may have no idea that a proxy somewhere along the way
ac92ced5bb41def1d90f871d6c8cfec2b03c0c7dBenjamin Franzke * translated the request to another ip:port
ac92ced5bb41def1d90f871d6c8cfec2b03c0c7dBenjamin Franzke * - except for the addresses from the VirtualHost line, none of the other
ac92ced5bb41def1d90f871d6c8cfec2b03c0c7dBenjamin Franzke * names we'll match have ports associated with them
ac92ced5bb41def1d90f871d6c8cfec2b03c0c7dBenjamin Franzke */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *host = r->hostname;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_port_t port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *s;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek server_rec *last_s;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek name_chain *src;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek last_s = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek port = r->connection->local_addr->port;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Recall that the name_chain is a list of server_addr_recs, some of
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * whose ports may not match. Also each server may appear more than
e0ea94c1e2ab3930c85c6057189a2a829a13a800Lennart Poettering * once in the chain -- specifically, it will appear once for each
e0ea94c1e2ab3930c85c6057189a2a829a13a800Lennart Poettering * address from its VirtualHost line which matched. We only want to
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * do the full ServerName/ServerAlias comparisons once for each
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * server, fortunately we know that all the VirtualHost addresses for
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * a single server are adjacent to each other.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering for (src = r->connection->vhost_lookup_data; src; src = src->next) {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering server_addr_rec *sar;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering /* We only consider addresses on the name_chain which have a matching
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering * port
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering */
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering sar = src->sar;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering if (sar->host_port != 0 && port != sar->host_port) {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering continue;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek s = src->server;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* does it match the virthost from the sar? */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!strcasecmp(host, sar->virthost)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek goto found;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (s == last_s) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* we've already done ServerName and ServerAlias checks for this
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * vhost
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek continue;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek last_s = s;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (matches_aliases(s, host)) {
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering goto found;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering }
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering return;
6e9efa59209d48fc69a456fbadb2b5c113f503a6Lennart Poettering
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekfound:
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* s is the first matching server, we're done */
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek r->server = s;
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek}
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;
}