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 * http://www.apache.org/licenses/LICENSE-2.0
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 * @brief functions pertaining to virtual host addresses
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * (configuration and run-time)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* we know core's module_index is 0 */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * After all the definitions there's an explanation of how it's all put
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * lists of name-vhosts.
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/* meta-list of ip addresses. Each server_rec can be in possibly multiple
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * hash chains since it can have multiple ips.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_addr_rec *sar; /* the record causing it to be in
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * this chain (need for both ip addr and port
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * comparisons) */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann server_rec *server; /* the server to use if this matches */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann name_chain *names; /* if non-NULL then a list of name-vhosts
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * sharing this address */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann name_chain *initialnames; /* no runtime use, temporary storage of first
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * NVH'es names */
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/* A (n) bucket hash table, each entry has a pointer to a server rec and
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * a pointer to the other entries in that bucket. Each individual address,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * even for virtualhosts with multiple addresses, has an entry in this hash
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * table. There are extra buckets for _default_, and name-vhost entries.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Note that after config time this is constant, so it is thread-safe.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* dump out statistics about the hash function */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* #define IPHASH_STATISTICS */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* list of the _default_ servers */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* whether a config error was seen */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* config check function */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * How it's used:
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * The ip address determines which chain in iphash_table is interesting, then
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * a comparison is done down that chain to find the first ipaddr_chain whose
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * sar matches the address:port pair.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Otherwise it's a name-vhost list, and the default is the server in the
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ipaddr_chain record. We tuck away the ipaddr_chain record in the
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * conn_rec field vhost_lookup_data. Later on after the headers we get a
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * second chance, and we use the name_chain to figure out what name-vhost
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * matches the headers.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * If there was no ip address match in the iphash_table then do a lookup
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * in the default_list.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * How it's put together ... well you should be able to figure that out
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * from how it's used. Or something like that.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* called at the beginning of the config */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel HoltmannAP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann memset(iphash_table, 0, sizeof(iphash_table));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Parses a host of the form <address>[:port]
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * paddr is used to create a list in the order of input
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * **paddr is the ->next pointer of the last entry (or s->addrs)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * *paddr is the variable used to keep track of **paddr between calls
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * port is the default port to assume
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic const char *get_addresses(apr_pool_t *p, const char *w_,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann wlen = strlen(w_); /* wlen must be > 0 at this point */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
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 return "The address or port is invalid";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "Missing address for VirtualHost";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "Scope ids are not supported";
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);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return "Could not resolve address '0.0.0.0' -- "
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "check resolver configuration.";
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann "Could not resolve host name %s -- ignoring!", host);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* Remember all addresses for the host */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann sar = apr_pcalloc(p, sizeof(server_addr_rec));
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* parse the <VirtualHost> addresses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannconst char *ap_parse_vhost_addrs(apr_pool_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* start the list of addreses */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* terminate the list */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* override the default port which is inherited from main_server */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel HoltmannAP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann static int warnonce = 0;
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/* 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 Holtmannstatic int iphash_compare(const void *a, const void *b)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return (*(const int *) b - *(const int *) a);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void dump_iphash_statistics(server_rec *main_s)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (src = iphash_table[i]; src; src = src->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't count the slop buckets in the total */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "iphash: total hashed = %u, avg chain = %u, "
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "chain lengths (count x len):",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann/* This hashing function is designed to get good distribution in the cases
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * where the server is handling entire "networks" of servers. i.e. a
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * whack of /24s. This is probably the most common configuration for
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * ISPs with large virtual servers.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * NOTE: This function is symmetric (i.e. collapses all 4 octets
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * into one), so machine byte order (big/little endianness) does not matter.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * Hash function provided by David Hankins.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic APR_INLINE unsigned hash_inaddr(unsigned key)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
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 key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic name_chain *new_name_chain(apr_pool_t *p,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* scan the hash table for an exact match first */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (trav = iphash_table[bucket]; trav; trav = trav->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't break, continue looking for an exact match */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic ipaddr_chain *find_default_server(apr_port_t port)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (trav = default_list; trav; trav = trav->next) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann if (wild_match == NULL && sar->host_port == 0) {
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* don't break, continue looking for an exact match */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmannstatic void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann len = apr_snprintf(buf, sizeof(buf), "*:%u",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server->defn_name, ic->server->defn_line_number);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%-22s is a NameVirtualHost\n"
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann "%8s default server %s (%s:%u)\n",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann ic->server->defn_name, ic->server->defn_line_number);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "namevhost %s (%s:%u)\n",
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann nc->server->defn_name, nc->server->defn_line_number);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_array_header_t *names = nc->server->names;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%16s alias %s\n", "", name[i]);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_array_header_t *names = nc->server->wild_names;
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann apr_file_printf(f, "VirtualHost configuration:\n");
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 /* wildcard servers */
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann for (ic = default_list; ic; ic = ic->next) {
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 Holtmannstatic void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* iterating backwards, so each one we see becomes the current default server */
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 /* second pass through this chain -- this really is an NVH, and we
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann * have two sets of names to link in.
94f5bbc626f2a4102debd9b17c964170a887cb49Marcel Holtmann /* 3rd or more -- just keep stacking the names */
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 ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* Main host first */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* initialize the tails */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
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 for (sar = s->addrs; sar; sar = sar->next) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
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 /* see if it matches something we've already got */
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 unsigned bucket = hash_addr(sar->host_addr);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann add_name_vhost_config(p, main_s, s, sar, ic);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* Ok now we want to set up a server_hostname if the user was
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * silly enough to forget one.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * XXX: This is silly we should just crash and burn.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = main_s->server_hostname;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann else if (!s->addrs) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* what else can we do? at this point this vhost has
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann no configured name, probably because they used
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann DNS in the VirtualHost statement. It's disabled
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann anyhow by the host matching code. -djg */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann apr_pstrdup(p, "bogus_host_without_forward_dns");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann s->server_hostname = apr_pstrdup(p, hostname);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* again, what can we do? They didn't specify a
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann ServerName, and their DNS isn't working. -djg */
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 apr_pstrdup(p, "bogus_host_without_reverse_dns");
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (ap_exists_config_define("DUMP_VHOSTS")) {
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmannstatic int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/*****************************************************************************
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * run-time vhost matching functions
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann/* Lowercase and remove any trailing dot and/or :port from the hostname,
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * and check that it is sane.
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * 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 const char *c;
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* According to RFC 2616, Host header field CAN be blank. */
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 for (c = r->hostname; apr_isdigit(*c); ++c);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann if (!*c) { /* pure integer */
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
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 r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann /* if the hostname is an IPv6 numeric address string, it was validated
5476ad087c0f2d45ab0dab1bab9ef3e9d70418bcMarcel Holtmann * already; otherwise, further validation is needed
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* leave char unchanged */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* strip trailing gubbins */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann "Client sent malformed Host header");
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann/* return 1 if host matches ServerName or ServerAliases */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmannstatic int matches_aliases(server_rec *s, const char *host)
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* match ServerName */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if (!strcasecmp(host, s->server_hostname)) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* search all the aliases from ServerAlias directive */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if(!name[i]) continue;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if(!name[i]) continue;
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann/* Suppose a request came in on the same socket as this r, and included
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * a header "Host: host:port", would it map to r->server? It's more
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * than just that though. When we do the normal matches for each request
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * we don't even bother considering Host: etc on non-namevirtualhosts,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * we just call it a match. But here we require the host:port to match
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * the ServerName and/or ServerAliases.
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel HoltmannAP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* search all the <VirtualHost> values */
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * NameVirtualHost 10.1.1.1
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * <VirtualHost 10.1.1.1>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * ServerName v1
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * </VirtualHost>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * <VirtualHost 10.1.1.1>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * ServerName v2
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * </VirtualHost>
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann * it would really go to v1.
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann for (sar = s->addrs; sar; sar = sar->next) {
c6f3f5b4b3ec439ae911ca0644237d96fd31893eMarcel Holtmann if ((sar->host_port == 0 || port == sar->host_port)
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann /* the Port has to match now, because the rest don't have ports associated
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann * with them. */
0234c599218518b1eb478d64d9883ba46e4ce5d8Marcel Holtmann * Even if the request has a Host: header containing a port we ignore
server_rec *s;
* do the full ServerName/ServerAlias comparisons once for each
goto found;
if (s == last_s) {
last_s = s;
goto found;
r->server = s;
server_rec *s;
if (s == last_s) {
last_s = s;
r->server = s;
fix_hostname(r);
if (r->hostname)
check_hostalias(r);
check_serverpath(r);
void* baton)
server_rec *s;
int rv = 0;
if (s == last_s) {
last_s = s;
if (rv != 0) {
return rv;
if (trav) {
if (trav) {