1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18 * @file  vhost.c
19 * @brief functions pertaining to virtual host addresses
20 *        (configuration and run-time)
21 */
22
23#include "apr.h"
24#include "apr_strings.h"
25#include "apr_lib.h"
26
27#define APR_WANT_STRFUNC
28#include "apr_want.h"
29
30#include "ap_config.h"
31#include "httpd.h"
32#include "http_config.h"
33#include "http_log.h"
34#include "http_vhost.h"
35#include "http_protocol.h"
36#include "http_core.h"
37
38#if APR_HAVE_ARPA_INET_H
39#include <arpa/inet.h>
40#endif
41
42/* we know core's module_index is 0 */
43#undef APLOG_MODULE_INDEX
44#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
45
46/*
47 * After all the definitions there's an explanation of how it's all put
48 * together.
49 */
50
51/* meta-list of name-vhosts.  Each server_rec can be in possibly multiple
52 * lists of name-vhosts.
53 */
54typedef struct name_chain name_chain;
55struct name_chain {
56    name_chain *next;
57    server_addr_rec *sar;       /* the record causing it to be in
58                                 * this chain (needed for port comparisons) */
59    server_rec *server;         /* the server to use on a match */
60};
61
62/* meta-list of ip addresses.  Each server_rec can be in possibly multiple
63 * hash chains since it can have multiple ips.
64 */
65typedef struct ipaddr_chain ipaddr_chain;
66struct ipaddr_chain {
67    ipaddr_chain *next;
68    server_addr_rec *sar;       /* the record causing it to be in
69                                 * this chain (need for both ip addr and port
70                                 * comparisons) */
71    server_rec *server;         /* the server to use if this matches */
72    name_chain *names;          /* if non-NULL then a list of name-vhosts
73                                 * sharing this address */
74    name_chain *initialnames;   /* no runtime use, temporary storage of first
75                                 * NVH'es names */
76};
77
78/* This defines the size of the hash table used for hashing ip addresses
79 * of virtual hosts.  It must be a power of two.
80 */
81#ifndef IPHASH_TABLE_SIZE
82#define IPHASH_TABLE_SIZE 256
83#endif
84
85/* A (n) bucket hash table, each entry has a pointer to a server rec and
86 * a pointer to the other entries in that bucket.  Each individual address,
87 * even for virtualhosts with multiple addresses, has an entry in this hash
88 * table.  There are extra buckets for _default_, and name-vhost entries.
89 *
90 * Note that after config time this is constant, so it is thread-safe.
91 */
92static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
93
94/* dump out statistics about the hash function */
95/* #define IPHASH_STATISTICS */
96
97/* list of the _default_ servers */
98static ipaddr_chain *default_list;
99
100/* whether a config error was seen */
101static int config_error = 0;
102
103/* config check function */
104static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
105                              apr_pool_t *ptemp, server_rec *s);
106
107/*
108 * How it's used:
109 *
110 * The ip address determines which chain in iphash_table is interesting, then
111 * a comparison is done down that chain to find the first ipaddr_chain whose
112 * sar matches the address:port pair.
113 *
114 * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
115 *
116 * Otherwise it's a name-vhost list, and the default is the server in the
117 * ipaddr_chain record.  We tuck away the ipaddr_chain record in the
118 * conn_rec field vhost_lookup_data.  Later on after the headers we get a
119 * second chance, and we use the name_chain to figure out what name-vhost
120 * matches the headers.
121 *
122 * If there was no ip address match in the iphash_table then do a lookup
123 * in the default_list.
124 *
125 * How it's put together ... well you should be able to figure that out
126 * from how it's used.  Or something like that.
127 */
128
129
130/* called at the beginning of the config */
131AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
132{
133    memset(iphash_table, 0, sizeof(iphash_table));
134    default_list = NULL;
135    ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
136}
137
138
139/*
140 * Parses a host of the form <address>[:port]
141 * paddr is used to create a list in the order of input
142 * **paddr is the ->next pointer of the last entry (or s->addrs)
143 * *paddr is the variable used to keep track of **paddr between calls
144 * port is the default port to assume
145 */
146static const char *get_addresses(apr_pool_t *p, const char *w_,
147                                 server_addr_rec ***paddr,
148                                 apr_port_t default_port)
149{
150    apr_sockaddr_t *my_addr;
151    server_addr_rec *sar;
152    char *w, *host, *scope_id;
153    int wild_port;
154    apr_size_t wlen;
155    apr_port_t port;
156    apr_status_t rv;
157
158    if (*w_ == '\0')
159        return NULL;
160
161    wlen = strlen(w_);                   /* wlen must be > 0 at this point */
162    w = apr_pstrmemdup(p, w_, wlen);
163    /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
164    wild_port = 0;
165    if (w[wlen - 1] == '*') {
166        if (wlen < 2) {
167            wild_port = 1;
168        }
169        else if (w[wlen - 2] == ':') {
170            w[wlen - 2] = '\0';
171            wild_port = 1;
172        }
173    }
174    rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
175    /* If the string is "80", apr_parse_addr_port() will be happy and set
176     * host to NULL and port to 80, so watch out for that.
177     */
178    if (rv != APR_SUCCESS) {
179        return "The address or port is invalid";
180    }
181    if (!host) {
182        return "Missing address for VirtualHost";
183    }
184    if (scope_id) {
185        return "Scope ids are not supported";
186    }
187    if (!port && !wild_port) {
188        port = default_port;
189    }
190
191    if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
192        rv = apr_sockaddr_info_get(&my_addr, NULL, APR_UNSPEC, port, 0, p);
193        if (rv) {
194            return "Could not determine a wildcard address ('0.0.0.0') -- "
195                "check resolver configuration.";
196        }
197    }
198    else {
199        rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
200        if (rv != APR_SUCCESS) {
201            ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00547)
202                "Could not resolve host name %s -- ignoring!", host);
203            return NULL;
204        }
205    }
206
207    /* Remember all addresses for the host */
208
209    do {
210        sar = apr_pcalloc(p, sizeof(server_addr_rec));
211        **paddr = sar;
212        *paddr = &sar->next;
213        sar->host_addr = my_addr;
214        sar->host_port = port;
215        sar->virthost = host;
216        my_addr = my_addr->next;
217    } while (my_addr);
218
219    return NULL;
220}
221
222
223/* parse the <VirtualHost> addresses */
224const char *ap_parse_vhost_addrs(apr_pool_t *p,
225                                 const char *hostname,
226                                 server_rec *s)
227{
228    server_addr_rec **addrs;
229    const char *err;
230
231    /* start the list of addreses */
232    addrs = &s->addrs;
233    while (hostname[0]) {
234        err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
235        if (err) {
236            *addrs = NULL;
237            return err;
238        }
239    }
240    /* terminate the list */
241    *addrs = NULL;
242    if (s->addrs) {
243        if (s->addrs->host_port) {
244            /* override the default port which is inherited from main_server */
245            s->port = s->addrs->host_port;
246        }
247    }
248    return NULL;
249}
250
251
252AP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
253                                                        void *dummy,
254                                                        const char *arg)
255{
256    static int warnonce = 0;
257    if (++warnonce == 1) {
258        ap_log_error(APLOG_MARK, APLOG_NOTICE|APLOG_STARTUP, APR_SUCCESS, NULL, APLOGNO(00548)
259                     "NameVirtualHost has no effect and will be removed in the "
260                     "next release %s:%d",
261                     cmd->directive->filename,
262                     cmd->directive->line_num);
263    }
264
265    return NULL;
266}
267
268
269/* hash table statistics, keep this in here for the beta period so
270 * we can find out if the hash function is ok
271 */
272#ifdef IPHASH_STATISTICS
273static int iphash_compare(const void *a, const void *b)
274{
275    return (*(const int *) b - *(const int *) a);
276}
277
278
279static void dump_iphash_statistics(server_rec *main_s)
280{
281    unsigned count[IPHASH_TABLE_SIZE];
282    int i;
283    ipaddr_chain *src;
284    unsigned total;
285    char buf[HUGE_STRING_LEN];
286    char *p;
287
288    total = 0;
289    for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
290        count[i] = 0;
291        for (src = iphash_table[i]; src; src = src->next) {
292            ++count[i];
293            if (i < IPHASH_TABLE_SIZE) {
294                /* don't count the slop buckets in the total */
295                ++total;
296            }
297        }
298    }
299    qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
300    p = buf + apr_snprintf(buf, sizeof(buf),
301                           "iphash: total hashed = %u, avg chain = %u, "
302                           "chain lengths (count x len):",
303                           total, total / IPHASH_TABLE_SIZE);
304    total = 1;
305    for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
306        if (count[i - 1] != count[i]) {
307            p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
308                              total, count[i - 1]);
309            total = 1;
310        }
311        else {
312            ++total;
313        }
314    }
315    p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
316                      total, count[IPHASH_TABLE_SIZE - 1]);
317    ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
318}
319#endif
320
321
322/* This hashing function is designed to get good distribution in the cases
323 * where the server is handling entire "networks" of servers.  i.e. a
324 * whack of /24s.  This is probably the most common configuration for
325 * ISPs with large virtual servers.
326 *
327 * NOTE: This function is symmetric (i.e. collapses all 4 octets
328 * into one), so machine byte order (big/little endianness) does not matter.
329 *
330 * Hash function provided by David Hankins.
331 */
332static APR_INLINE unsigned hash_inaddr(unsigned key)
333{
334    key ^= (key >> 16);
335    return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
336}
337
338static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
339{
340    unsigned key;
341
342    /* The key is the last four bytes of the IP address.
343     * For IPv4, this is the entire address, as always.
344     * For IPv6, this is usually part of the MAC address.
345     */
346    key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
347    return hash_inaddr(key);
348}
349
350static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
351                                      server_rec *s, server_addr_rec *sar)
352{
353    ipaddr_chain *new;
354
355    new = apr_palloc(p, sizeof(*new));
356    new->names = NULL;
357    new->initialnames = NULL;
358    new->server = s;
359    new->sar = sar;
360    new->next = NULL;
361    return new;
362}
363
364
365static name_chain *new_name_chain(apr_pool_t *p,
366                                  server_rec *s, server_addr_rec *sar)
367{
368    name_chain *new;
369
370    new = apr_palloc(p, sizeof(*new));
371    new->server = s;
372    new->sar = sar;
373    new->next = NULL;
374    return new;
375}
376
377
378static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
379{
380    unsigned bucket;
381    ipaddr_chain *trav = NULL;
382    ipaddr_chain *wild_match = NULL;
383
384    /* scan the hash table for an exact match first */
385    bucket = hash_addr(sa);
386    for (trav = iphash_table[bucket]; trav; trav = trav->next) {
387        server_addr_rec *sar = trav->sar;
388        apr_sockaddr_t *cur = sar->host_addr;
389
390        if (cur->port == sa->port) {
391            if (apr_sockaddr_equal(cur, sa)) {
392                return trav;
393            }
394        }
395        if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
396            if (apr_sockaddr_equal(cur, sa)) {
397                /* don't break, continue looking for an exact match */
398                wild_match = trav;
399            }
400        }
401    }
402    return wild_match;
403}
404
405static ipaddr_chain *find_default_server(apr_port_t port)
406{
407    server_addr_rec *sar;
408    ipaddr_chain *trav = NULL;
409    ipaddr_chain *wild_match = NULL;
410
411    for (trav = default_list; trav; trav = trav->next) {
412        sar = trav->sar;
413        if (sar->host_port == port) {
414            /* match! */
415            return trav;
416        }
417        if (wild_match == NULL && sar->host_port == 0) {
418            /* don't break, continue looking for an exact match */
419            wild_match = trav;
420        }
421    }
422    return wild_match;
423}
424
425#if APR_HAVE_IPV6
426#define IS_IN6_ANYADDR(ad) ((ad)->family == APR_INET6                   \
427                            && IN6_IS_ADDR_UNSPECIFIED(&(ad)->sa.sin6.sin6_addr))
428#else
429#define IS_IN6_ANYADDR(ad) (0)
430#endif
431
432static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
433{
434    name_chain *nc;
435    int len;
436    char buf[MAX_STRING_LEN];
437    apr_sockaddr_t *ha = ic->sar->host_addr;
438
439    if ((ha->family == APR_INET && ha->sa.sin.sin_addr.s_addr == INADDR_ANY)
440        || IS_IN6_ANYADDR(ha)) {
441        len = apr_snprintf(buf, sizeof(buf), "*:%u",
442                           ic->sar->host_port);
443    }
444    else {
445        len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
446    }
447    if (ic->sar->host_port == 0) {
448        buf[len-1] = '*';
449    }
450    if (ic->names == NULL) {
451        apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
452                        ic->server->server_hostname,
453                        ic->server->defn_name, ic->server->defn_line_number);
454        return;
455    }
456    apr_file_printf(f, "%-22s is a NameVirtualHost\n"
457                    "%8s default server %s (%s:%u)\n",
458                    buf, "", ic->server->server_hostname,
459                    ic->server->defn_name, ic->server->defn_line_number);
460    for (nc = ic->names; nc; nc = nc->next) {
461        if (nc->sar->host_port) {
462            apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
463        }
464        else {
465            apr_file_printf(f, "%8s port * ", "");
466        }
467        apr_file_printf(f, "namevhost %s (%s:%u)\n",
468                        nc->server->server_hostname,
469                        nc->server->defn_name, nc->server->defn_line_number);
470        if (nc->server->names) {
471            apr_array_header_t *names = nc->server->names;
472            char **name = (char **)names->elts;
473            int i;
474            for (i = 0; i < names->nelts; ++i) {
475                if (name[i]) {
476                    apr_file_printf(f, "%16s alias %s\n", "", name[i]);
477                }
478            }
479        }
480        if (nc->server->wild_names) {
481            apr_array_header_t *names = nc->server->wild_names;
482            char **name = (char **)names->elts;
483            int i;
484            for (i = 0; i < names->nelts; ++i) {
485                if (name[i]) {
486                    apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
487                }
488            }
489        }
490    }
491}
492
493static void dump_vhost_config(apr_file_t *f)
494{
495    ipaddr_chain *ic;
496    int i;
497
498    apr_file_printf(f, "VirtualHost configuration:\n");
499
500    /* non-wildcard servers */
501    for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
502        for (ic = iphash_table[i]; ic; ic = ic->next) {
503            dump_a_vhost(f, ic);
504        }
505    }
506
507    /* wildcard servers */
508    for (ic = default_list; ic; ic = ic->next) {
509        dump_a_vhost(f, ic);
510    }
511}
512
513
514/*
515 * When a second or later virtual host maps to the same IP chain,
516 * add the relevant server names to the chain.  Special care is taken
517 * to avoid adding ic->names until we're sure there are multiple VH'es.
518 */
519static void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
520                                 server_rec *s, server_addr_rec *sar,
521                                 ipaddr_chain *ic)
522{
523
524   name_chain *nc = new_name_chain(p, s, sar);
525   nc->next = ic->names;
526
527   /* iterating backwards, so each one we see becomes the current default server */
528   ic->server = s;
529
530   if (ic->names == NULL) {
531       if (ic->initialnames == NULL) {
532           /* first pass, set these names aside in case we see another VH.
533            * Until then, this looks like an IP-based VH to runtime.
534            */
535           ic->initialnames = nc;
536       }
537       else {
538           /* second pass through this chain -- this really is an NVH, and we
539            * have two sets of names to link in.
540            */
541           nc->next = ic->initialnames;
542           ic->names = nc;
543           ic->initialnames = NULL;
544       }
545   }
546   else {
547       /* 3rd or more -- just keep stacking the names */
548       ic->names = nc;
549   }
550}
551
552/* compile the tables and such we need to do the run-time vhost lookups */
553AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
554{
555    server_addr_rec *sar;
556    int has_default_vhost_addr;
557    server_rec *s;
558    int i;
559    ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
560
561    /* Main host first */
562    s = main_s;
563
564    if (!s->server_hostname) {
565        s->server_hostname = ap_get_local_host(p);
566    }
567
568    /* initialize the tails */
569    for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
570        iphash_table_tail[i] = &iphash_table[i];
571    }
572
573    /* The next things to go into the hash table are the virtual hosts
574     * themselves.  They're listed off of main_s->next in the reverse
575     * order they occured in the config file, so we insert them at
576     * the iphash_table_tail but don't advance the tail.
577     */
578
579    for (s = main_s->next; s; s = s->next) {
580        server_addr_rec *sar_prev = NULL;
581        has_default_vhost_addr = 0;
582        for (sar = s->addrs; sar; sar = sar->next) {
583            ipaddr_chain *ic;
584            char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
585            /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */
586            if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
587                ic = find_default_server(sar->host_port);
588
589                if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server"  */
590                    if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len)
591                                  || sar_prev->host_port != sar->host_port) {
592                        add_name_vhost_config(p, main_s, s, sar, ic);
593                    }
594                }
595                else {
596                    /* No default server, or we found a default server but
597                    ** exactly one of us is a wildcard port, which means we want
598                    ** two ip-based vhosts not an NVH with two names
599                    */
600                    ic = new_ipaddr_chain(p, s, sar);
601                    ic->next = default_list;
602                    default_list = ic;
603                    add_name_vhost_config(p, main_s, s, sar, ic);
604                }
605                has_default_vhost_addr = 1;
606            }
607            else {
608                /* see if it matches something we've already got */
609                ic = find_ipaddr(sar->host_addr);
610
611                if (!ic || sar->host_port != ic->sar->host_port) {
612                    /* No matching server, or we found a matching server but
613                    ** exactly one of us is a wildcard port, which means we want
614                    ** two ip-based vhosts not an NVH with two names
615                    */
616                    unsigned bucket = hash_addr(sar->host_addr);
617                    ic = new_ipaddr_chain(p, s, sar);
618                    ic->next = *iphash_table_tail[bucket];
619                    *iphash_table_tail[bucket] = ic;
620                }
621                add_name_vhost_config(p, main_s, s, sar, ic);
622            }
623            sar_prev = sar;
624        }
625
626        /* Ok now we want to set up a server_hostname if the user was
627         * silly enough to forget one.
628         * XXX: This is silly we should just crash and burn.
629         */
630        if (!s->server_hostname) {
631            if (has_default_vhost_addr) {
632                s->server_hostname = main_s->server_hostname;
633            }
634            else if (!s->addrs) {
635                /* what else can we do?  at this point this vhost has
636                    no configured name, probably because they used
637                    DNS in the VirtualHost statement.  It's disabled
638                    anyhow by the host matching code.  -djg */
639                s->server_hostname =
640                    apr_pstrdup(p, "bogus_host_without_forward_dns");
641            }
642            else {
643                apr_status_t rv;
644                char *hostname;
645
646                rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
647                if (rv == APR_SUCCESS) {
648                    s->server_hostname = apr_pstrdup(p, hostname);
649                }
650                else {
651                    /* again, what can we do?  They didn't specify a
652                       ServerName, and their DNS isn't working. -djg */
653                    char *ipaddr_str;
654
655                    apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
656                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s, APLOGNO(00549)
657                                 "Failed to resolve server name "
658                                 "for %s (check DNS) -- or specify an explicit "
659                                 "ServerName",
660                                 ipaddr_str);
661                    s->server_hostname =
662                        apr_pstrdup(p, "bogus_host_without_reverse_dns");
663                }
664            }
665        }
666    }
667
668#ifdef IPHASH_STATISTICS
669    dump_iphash_statistics(main_s);
670#endif
671    if (ap_exists_config_define("DUMP_VHOSTS")) {
672        apr_file_t *thefile = NULL;
673        apr_file_open_stdout(&thefile, p);
674        dump_vhost_config(thefile);
675    }
676}
677
678static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
679                              apr_pool_t *ptemp, server_rec *s)
680{
681    return config_error ? !OK : OK;
682}
683
684/*****************************************************************************
685 * run-time vhost matching functions
686 */
687
688/* Lowercase and remove any trailing dot and/or :port from the hostname,
689 * and check that it is sane.
690 *
691 * In most configurations the exact syntax of the hostname isn't
692 * important so strict sanity checking isn't necessary. However, in
693 * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
694 * the hostname is interpolated into the filename, we need to be sure
695 * that the interpolation doesn't expose parts of the filesystem.
696 * We don't do strict RFC 952 / RFC 1123 syntax checking in order
697 * to support iDNS and people who erroneously use underscores.
698 * Instead we just check for filesystem metacharacters: directory
699 * separators / and \ and sequences of more than one dot.
700 */
701static void fix_hostname(request_rec *r)
702{
703    char *host, *scope_id;
704    char *dst;
705    apr_port_t port;
706    apr_status_t rv;
707    const char *c;
708
709    /* According to RFC 2616, Host header field CAN be blank. */
710    if (!*r->hostname) {
711        return;
712    }
713
714    /* apr_parse_addr_port will interpret a bare integer as a port
715     * which is incorrect in this context.  So treat it separately.
716     */
717    for (c = r->hostname; apr_isdigit(*c); ++c);
718    if (!*c) {  /* pure integer */
719        return;
720    }
721
722    rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
723    if (rv != APR_SUCCESS || scope_id) {
724        goto bad;
725    }
726
727    if (port) {
728        /* Don't throw the Host: header's port number away:
729           save it in parsed_uri -- ap_get_server_port() needs it! */
730        /* @@@ XXX there should be a better way to pass the port.
731         *         Like r->hostname, there should be a r->portno
732         */
733        r->parsed_uri.port = port;
734        r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
735    }
736
737    /* if the hostname is an IPv6 numeric address string, it was validated
738     * already; otherwise, further validation is needed
739     */
740    if (r->hostname[0] != '[') {
741        for (dst = host; *dst; dst++) {
742            if (apr_islower(*dst)) {
743                /* leave char unchanged */
744            }
745            else if (*dst == '.') {
746                if (*(dst + 1) == '.') {
747                    goto bad;
748                }
749            }
750            else if (apr_isupper(*dst)) {
751                *dst = apr_tolower(*dst);
752            }
753            else if (*dst == '/' || *dst == '\\') {
754                goto bad;
755            }
756        }
757        /* strip trailing gubbins */
758        if (dst > host && dst[-1] == '.') {
759            dst[-1] = '\0';
760        }
761    }
762    r->hostname = host;
763    return;
764
765bad:
766    r->status = HTTP_BAD_REQUEST;
767    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550)
768                  "Client sent malformed Host header: %s",
769                  r->hostname);
770    return;
771}
772
773
774/* return 1 if host matches ServerName or ServerAliases */
775static int matches_aliases(server_rec *s, const char *host)
776{
777    int i;
778    apr_array_header_t *names;
779
780    /* match ServerName */
781    if (!strcasecmp(host, s->server_hostname)) {
782        return 1;
783    }
784
785    /* search all the aliases from ServerAlias directive */
786    names = s->names;
787    if (names) {
788        char **name = (char **) names->elts;
789        for (i = 0; i < names->nelts; ++i) {
790            if(!name[i]) continue;
791            if (!strcasecmp(host, name[i]))
792                return 1;
793        }
794    }
795    names = s->wild_names;
796    if (names) {
797        char **name = (char **) names->elts;
798        for (i = 0; i < names->nelts; ++i) {
799            if(!name[i]) continue;
800            if (!ap_strcasecmp_match(host, name[i]))
801                return 1;
802        }
803    }
804    return 0;
805}
806
807
808/* Suppose a request came in on the same socket as this r, and included
809 * a header "Host: host:port", would it map to r->server?  It's more
810 * than just that though.  When we do the normal matches for each request
811 * we don't even bother considering Host: etc on non-namevirtualhosts,
812 * we just call it a match.  But here we require the host:port to match
813 * the ServerName and/or ServerAliases.
814 */
815AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
816                                         apr_port_t port)
817{
818    server_rec *s;
819    server_addr_rec *sar;
820
821    s = r->server;
822
823    /* search all the <VirtualHost> values */
824    /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
825     * consider:
826     *
827     *     NameVirtualHost 10.1.1.1
828     *     <VirtualHost 10.1.1.1>
829     *     ServerName v1
830     *     </VirtualHost>
831     *     <VirtualHost 10.1.1.1>
832     *     ServerName v2
833     *     </VirtualHost>
834     *
835     * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll say
836     * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
837     * it would really go to v1.
838     */
839    for (sar = s->addrs; sar; sar = sar->next) {
840        if ((sar->host_port == 0 || port == sar->host_port)
841            && !strcasecmp(host, sar->virthost)) {
842            return 1;
843        }
844    }
845
846    /* the Port has to match now, because the rest don't have ports associated
847     * with them. */
848    if (port != s->port) {
849        return 0;
850    }
851
852    return matches_aliases(s, host);
853}
854
855
856static void check_hostalias(request_rec *r)
857{
858    /*
859     * Even if the request has a Host: header containing a port we ignore
860     * that port.  We always use the physical port of the socket.  There
861     * are a few reasons for this:
862     *
863     * - the default of 80 or 443 for SSL is easier to handle this way
864     * - there is less of a possibility of a security problem
865     * - it simplifies the data structure
866     * - the client may have no idea that a proxy somewhere along the way
867     *   translated the request to another ip:port
868     * - except for the addresses from the VirtualHost line, none of the other
869     *   names we'll match have ports associated with them
870     */
871    const char *host = r->hostname;
872    apr_port_t port;
873    server_rec *s;
874    server_rec *virthost_s;
875    server_rec *last_s;
876    name_chain *src;
877
878    virthost_s = NULL;
879    last_s = NULL;
880
881    port = r->connection->local_addr->port;
882
883    /* Recall that the name_chain is a list of server_addr_recs, some of
884     * whose ports may not match.  Also each server may appear more than
885     * once in the chain -- specifically, it will appear once for each
886     * address from its VirtualHost line which matched.  We only want to
887     * do the full ServerName/ServerAlias comparisons once for each
888     * server, fortunately we know that all the VirtualHost addresses for
889     * a single server are adjacent to each other.
890     */
891
892    for (src = r->connection->vhost_lookup_data; src; src = src->next) {
893        server_addr_rec *sar;
894
895        /* We only consider addresses on the name_chain which have a matching
896         * port
897         */
898        sar = src->sar;
899        if (sar->host_port != 0 && port != sar->host_port) {
900            continue;
901        }
902
903        s = src->server;
904
905        /* If we still need to do ServerName and ServerAlias checks for this
906         * server, do them now.
907         */
908        if (s != last_s) {
909            /* does it match any ServerName or ServerAlias directive? */
910            if (matches_aliases(s, host)) {
911                goto found;
912            }
913        }
914        last_s = s;
915
916        /* Fallback: does it match the virthost from the sar? */
917        if (!strcasecmp(host, sar->virthost)) {
918            /* only the first match is used */
919            if (virthost_s == NULL) {
920                virthost_s = s;
921            }
922        }
923    }
924
925    /* If ServerName and ServerAlias check failed, we end up here.  If it
926     * matches a VirtualHost, virthost_s is set. Use that as fallback
927     */
928    if (virthost_s) {
929        s = virthost_s;
930        goto found;
931    }
932
933    return;
934
935found:
936    /* s is the first matching server, we're done */
937    r->server = s;
938}
939
940
941static void check_serverpath(request_rec *r)
942{
943    server_rec *s;
944    server_rec *last_s;
945    name_chain *src;
946    apr_port_t port;
947
948    port = r->connection->local_addr->port;
949
950    /*
951     * This is in conjunction with the ServerPath code in http_core, so we
952     * get the right host attached to a non- Host-sending request.
953     *
954     * See the comment in check_hostalias about how each vhost can be
955     * listed multiple times.
956     */
957
958    last_s = NULL;
959    for (src = r->connection->vhost_lookup_data; src; src = src->next) {
960        /* We only consider addresses on the name_chain which have a matching
961         * port
962         */
963        if (src->sar->host_port != 0 && port != src->sar->host_port) {
964            continue;
965        }
966
967        s = src->server;
968        if (s == last_s) {
969            continue;
970        }
971        last_s = s;
972
973        if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
974            (s->path[s->pathlen - 1] == '/' ||
975             r->uri[s->pathlen] == '/' ||
976             r->uri[s->pathlen] == '\0')) {
977            r->server = s;
978            return;
979        }
980    }
981}
982
983
984AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
985{
986    /* must set this for HTTP/1.1 support */
987    if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
988        fix_hostname(r);
989        if (r->status != HTTP_OK)
990            return;
991    }
992    /* check if we tucked away a name_chain */
993    if (r->connection->vhost_lookup_data) {
994        if (r->hostname)
995            check_hostalias(r);
996        else
997            check_serverpath(r);
998    }
999}
1000
1001/**
1002 * For every virtual host on this connection, call func_cb.
1003 */
1004AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
1005                                            ap_vhost_iterate_conn_cb func_cb,
1006                                            void* baton)
1007{
1008    server_rec *s;
1009    server_rec *last_s;
1010    name_chain *src;
1011    apr_port_t port;
1012    int rv = 0;
1013
1014    if (conn->vhost_lookup_data) {
1015        last_s = NULL;
1016        port = conn->local_addr->port;
1017
1018        for (src = conn->vhost_lookup_data; src; src = src->next) {
1019            server_addr_rec *sar;
1020
1021            /* We only consider addresses on the name_chain which have a
1022             * matching port.
1023             */
1024            sar = src->sar;
1025            if (sar->host_port != 0 && port != sar->host_port) {
1026                continue;
1027            }
1028
1029            s = src->server;
1030
1031            if (s == last_s) {
1032                /* we've already done a callback for this vhost. */
1033                continue;
1034            }
1035
1036            last_s = s;
1037
1038            rv = func_cb(baton, conn, s);
1039
1040            if (rv != 0) {
1041                break;
1042            }
1043        }
1044    }
1045    else {
1046        rv = func_cb(baton, conn, conn->base_server);
1047    }
1048
1049    return rv;
1050}
1051
1052/* Called for a new connection which has a known local_addr.  Note that the
1053 * new connection is assumed to have conn->server == main server.
1054 */
1055AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
1056{
1057    ipaddr_chain *trav;
1058    apr_port_t port;
1059
1060    /* scan the hash table for an exact match first */
1061    trav = find_ipaddr(conn->local_addr);
1062
1063    if (trav) {
1064        /* save the name_chain for later in case this is a name-vhost */
1065        conn->vhost_lookup_data = trav->names;
1066        conn->base_server = trav->server;
1067        return;
1068    }
1069
1070    /* maybe there's a default server or wildcard name-based vhost
1071     * matching this port
1072     */
1073    port = conn->local_addr->port;
1074
1075    trav = find_default_server(port);
1076    if (trav) {
1077        conn->vhost_lookup_data = trav->names;
1078        conn->base_server = trav->server;
1079        return;
1080    }
1081
1082    /* otherwise we're stuck with just the main server
1083     * and no name-based vhosts
1084     */
1085    conn->vhost_lookup_data = NULL;
1086}
1087