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