]> granicus.if.org Git - apache/blob - server/vhost.c
Fix a segfault when a numeric host (e.g., "Host: 123") was specified.
[apache] / server / vhost.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2001 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 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);
198     if (wlen > 2 && w[wlen - 1] == '*' && w[wlen - 2] == ':') {
199         w[wlen - 2] = '\0';
200         wild_port = 1;
201     }
202     else {
203         wild_port = 0;
204     }
205     rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
206     if (rv != APR_SUCCESS) {
207         return "The address or port is invalid";
208     }
209     if (scope_id) {
210         return "Scope ids are not supported";
211     }
212     if (!port && !wild_port) {
213         port = default_port;
214     }
215
216     if (strcmp(host, "*") == 0) {
217         rv = apr_sockaddr_info_get(&my_addr, NULL, APR_INET, port, 0, p);
218         my_addr->sa.sin.sin_addr.s_addr = htonl(INADDR_ANY);
219     } else if (strcasecmp(host, "_default_") == 0
220         || strcmp(host, "255.255.255.255") == 0) {
221         rv = apr_sockaddr_info_get(&my_addr, NULL, APR_INET, port, 0, p);
222         ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */
223         my_addr->sa.sin.sin_addr.s_addr = DEFAULT_VHOST_ADDR;
224     } else {
225         rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
226         if (rv != APR_SUCCESS) {
227             ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
228                 "Cannot resolve host name %s --- ignoring!", host);
229             return NULL;
230         }
231     }
232
233     /* XXX Gotta go through *all* addresses for the host name! 
234      * Fix apr_sockaddr_info_get() to save them! */
235
236     sar = apr_pcalloc(p, sizeof(server_addr_rec));
237     **paddr = sar;
238     *paddr = &sar->next;
239     sar->host_addr = my_addr;
240     sar->host_port = port;
241     sar->virthost = host;
242     return NULL;
243 }
244
245
246 /* parse the <VirtualHost> addresses */
247 const char *ap_parse_vhost_addrs(apr_pool_t *p, const char *hostname, server_rec *s)
248 {
249     server_addr_rec **addrs;
250     const char *err;
251
252     /* start the list of addreses */
253     addrs = &s->addrs;
254     while (hostname[0]) {
255         err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
256         if (err) {
257             *addrs = NULL;
258             return err;
259         }
260     }
261     /* terminate the list */
262     *addrs = NULL;
263     if (s->addrs) {
264         if (s->addrs->host_port) {
265             /* override the default port which is inherited from main_server */
266             s->port = s->addrs->host_port;
267         }
268     }
269     return NULL;
270 }
271
272
273 const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy,
274                                       const char *arg)
275 {
276     /* use whatever port the main server has at this point */
277     return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
278                             cmd->server->port);
279 }
280
281
282 /* hash apr_table_t statistics, keep this in here for the beta period so
283  * we can find out if the hash function is ok
284  */
285 #ifdef IPHASH_STATISTICS
286 static int iphash_compare(const void *a, const void *b)
287 {
288     return (*(const int *) b - *(const int *) a);
289 }
290
291
292 static void dump_iphash_statistics(server_rec *main_s)
293 {
294     unsigned count[IPHASH_TABLE_SIZE];
295     int i;
296     ipaddr_chain *src;
297     unsigned total;
298     char buf[HUGE_STRING_LEN];
299     char *p;
300
301     total = 0;
302     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
303         count[i] = 0;
304         for (src = iphash_table[i]; src; src = src->next) {
305             ++count[i];
306             if (i < IPHASH_TABLE_SIZE) {
307                 /* don't count the slop buckets in the total */
308                 ++total;
309             }
310         }
311     }
312     qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
313     p = buf + apr_snprintf(buf, sizeof(buf),
314                     "iphash: total hashed = %u, avg chain = %u, "
315                     "chain lengths (count x len):",
316                     total, total / IPHASH_TABLE_SIZE);
317     total = 1;
318     for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
319         if (count[i - 1] != count[i]) {
320             p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
321                              total, count[i - 1]);
322             total = 1;
323         }
324         else {
325             ++total;
326         }
327     }
328     p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
329                      total, count[IPHASH_TABLE_SIZE - 1]);
330     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, main_s, buf);
331 }
332 #endif
333
334
335 /* This hashing function is designed to get good distribution in the cases
336  * where the server is handling entire "networks" of servers.  i.e. a
337  * whack of /24s.  This is probably the most common configuration for
338  * ISPs with large virtual servers.
339  *
340  * NOTE: This function is symmetric (i.e. collapses all 4 octets
341  * into one), so machine byte order (big/little endianness) does not matter.
342  *
343  * Hash function provided by David Hankins.
344  */
345 static APR_INLINE unsigned hash_inaddr(unsigned key)
346 {
347     key ^= (key >> 16);
348     return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
349 }
350
351 static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
352 {
353     unsigned key;
354
355     /* The key is the last four bytes of the IP address.
356      * For IPv4, this is the entire address, as always.
357      * For IPv6, this is usually part of the MAC address.
358      */
359     key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
360     return hash_inaddr(key);
361 }
362
363 static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
364                                     server_rec *s, server_addr_rec *sar)
365 {
366     ipaddr_chain *new;
367
368     new = apr_palloc(p, sizeof(*new));
369     new->names = NULL;
370     new->server = s;
371     new->sar = sar;
372     new->next = NULL;
373     return new;
374 }
375
376
377 static name_chain *new_name_chain(apr_pool_t *p, server_rec *s, server_addr_rec *sar)
378 {
379     name_chain *new;
380
381     new = apr_palloc(p, sizeof(*new));
382     new->server = s;
383     new->sar = sar;
384     new->next = NULL;
385     return new;
386 }
387
388
389 static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
390 {
391     unsigned bucket;
392     ipaddr_chain *trav;
393
394     /* scan the hash apr_table_t for an exact match first */
395     bucket = hash_addr(sa);
396     for (trav = iphash_table[bucket]; trav; trav = trav->next) {
397         server_addr_rec *sar = trav->sar;
398         apr_sockaddr_t *cur = sar->host_addr;
399
400         if (cur->sa.sin.sin_port == 0 ||
401             sa->sa.sin.sin_port == 0  ||
402             cur->sa.sin.sin_port == sa->sa.sin.sin_port) {
403             if (cur->ipaddr_len == sa->ipaddr_len &&
404                 !memcmp(cur->ipaddr_ptr,
405                         sa->ipaddr_ptr,
406                         sa->ipaddr_len)) {
407                 return trav;
408             }
409         }    
410     }
411     return NULL;
412 }
413
414
415 static ipaddr_chain *find_default_server(apr_port_t port)
416 {
417     server_addr_rec *sar;
418     ipaddr_chain *trav;
419
420     for (trav = default_list; trav; trav = trav->next) {
421         sar = trav->sar;
422         if (sar->host_port == 0 || sar->host_port == port) {
423             /* match! */
424             return trav;
425         }
426     }
427     return NULL;
428 }
429
430 static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
431 {
432     name_chain *nc;
433     int len;
434     char buf[MAX_STRING_LEN];
435     apr_sockaddr_t *ha = ic->sar->host_addr;
436
437     if (ha->sa.sin.sin_family == APR_INET &&
438         ha->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) {
439         len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
440                 ic->sar->host_port);
441     }
442     else if (ha->sa.sin.sin_family == APR_INET &&
443              ha->sa.sin.sin_addr.s_addr == INADDR_ANY) {
444         len = apr_snprintf(buf, sizeof(buf), "*:%u",
445                 ic->sar->host_port);
446     }
447     else {
448         len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
449     }
450     if (ic->sar->host_port == 0) {
451         buf[len-1] = '*';
452     }
453     if (ic->names == NULL) {
454         apr_file_printf(f, "%-22s %s (%s:%u)\n", buf, ic->server->server_hostname,
455                 ic->server->defn_name, ic->server->defn_line_number);
456         return;
457     }
458     apr_file_printf(f, "%-22s is a NameVirtualHost\n"
459             "%8s default server %s (%s:%u)\n",
460             buf, "", ic->server->server_hostname,
461             ic->server->defn_name, ic->server->defn_line_number);
462     for (nc = ic->names; nc; nc = nc->next) {
463         if (nc->sar->host_port) {
464             apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
465         }
466         else {
467             apr_file_printf(f, "%8s port * ", "");
468         }
469         apr_file_printf(f, "namevhost %s (%s:%u)\n", nc->server->server_hostname,
470                 nc->server->defn_name, nc->server->defn_line_number);
471     }
472 }
473
474 static void dump_vhost_config(apr_file_t *f)
475 {
476     ipaddr_chain *ic;
477     int i;
478
479     apr_file_printf(f, "VirtualHost configuration:\n");
480     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
481         for (ic = iphash_table[i]; ic; ic = ic->next) {
482             dump_a_vhost(f, ic);
483         }
484     }
485     if (default_list) {
486         apr_file_printf(f, "wildcard NameVirtualHosts and _default_ servers:\n");
487         for (ic = default_list; ic; ic = ic->next) {
488             dump_a_vhost(f, ic);
489         }
490     }
491 }
492
493 /*
494  * Two helper functions for ap_fini_vhost_config()
495  */
496 static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s, server_rec *s,
497                                  server_addr_rec *sar, ipaddr_chain *ic)
498 {
499     /* the first time we encounter a NameVirtualHost address
500      * ic->server will be NULL, on subsequent encounters
501      * ic->names will be non-NULL.
502      */
503     if (ic->names || ic->server == NULL) {
504         name_chain *nc = new_name_chain(p, s, sar);
505         nc->next = ic->names;
506         ic->names = nc;
507         ic->server = s;
508         if (sar->host_port != ic->sar->host_port) {
509             /* one of the two is a * port, the other isn't */
510             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
511                     "VirtualHost %s:%u -- mixing * "
512                     "ports and non-* ports with "
513                     "a NameVirtualHost address is not supported,"
514                     " proceeding with undefined results",
515                     sar->virthost, sar->host_port);
516         }
517         return 1;
518     }
519     else {
520         /* IP-based vhosts are handled by the caller */
521         return 0;
522     }
523 }
524
525 static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic)
526 {
527     while (*pic) {
528         ipaddr_chain *ic = *pic;
529         
530         if (ic->server == NULL) {
531             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
532                          "NameVirtualHost %s:%u has no VirtualHosts",
533                          ic->sar->virthost, ic->sar->host_port);
534             *pic = ic->next;
535         }
536         else if (ic->names == NULL) {
537             /* if server != NULL and names == NULL then we're done
538              * looking at NameVirtualHosts
539              */
540             break;
541         }
542         else {
543             pic = &ic->next;
544         }
545     }
546 }
547
548 /* compile the tables and such we need to do the run-time vhost lookups */
549 AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
550 {
551     server_addr_rec *sar;
552     int has_default_vhost_addr;
553     server_rec *s;
554     int i;
555     ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
556
557     /* terminate the name_vhost list */
558     *name_vhost_list_tail = NULL;
559
560     /* Main host first */
561     s = main_s;
562
563     if (!s->server_hostname) {
564         s->server_hostname = ap_get_local_host(p);
565     }
566
567     /* initialize the tails */
568     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
569         iphash_table_tail[i] = &iphash_table[i];
570     }
571
572     /* The first things to go into the hash apr_table_t are the NameVirtualHosts
573      * Since name_vhost_list is in the same order that the directives
574      * occured in the config file, we'll copy it in that order.
575      */
576     for (sar = name_vhost_list; sar; sar = sar->next) {
577         unsigned bucket = hash_addr(sar->host_addr);
578         ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
579
580         if (sar->host_addr->sa.sin.sin_addr.s_addr != INADDR_ANY) {
581             *iphash_table_tail[bucket] = ic;
582             iphash_table_tail[bucket] = &ic->next;
583         }
584         else {
585             /* A wildcard NameVirtualHost goes on the default_list so
586              * that it can catch incoming requests on any address.
587              */
588             ic->next = default_list;
589             default_list = ic;
590         }
591         /* Notice that what we've done is insert an ipaddr_chain with
592          * both server and names NULL. This fact is used to spot name-
593          * based vhosts in add_name_vhost_config().
594          */
595     }
596
597     /* The next things to go into the hash apr_table_t are the virtual hosts
598      * themselves.  They're listed off of main_s->next in the reverse
599      * order they occured in the config file, so we insert them at
600      * the iphash_table_tail but don't advance the tail.
601      */
602
603     for (s = main_s->next; s; s = s->next) {
604         has_default_vhost_addr = 0;
605         for (sar = s->addrs; sar; sar = sar->next) {
606             ipaddr_chain *ic;
607
608             if (sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR
609                 || sar->host_addr->sa.sin.sin_addr.s_addr == INADDR_ANY) {
610                 ic = find_default_server(sar->host_port);
611                 if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
612                     if (ic && ic->sar->host_port != 0) {
613                         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
614                             0, main_s, "_default_ VirtualHost overlap on port %u,"
615                             " the first has precedence", sar->host_port);
616                     }
617                     ic = new_ipaddr_chain(p, s, sar);
618                     ic->next = default_list;
619                     default_list = ic;
620                 }
621                 has_default_vhost_addr = 1;
622             }
623             else {
624                 /* see if it matches something we've already got */
625                 ic = find_ipaddr(sar->host_addr);
626
627                 if (!ic) {
628                     unsigned bucket = hash_addr(sar->host_addr);
629
630                     ic = new_ipaddr_chain(p, s, sar);
631                     ic->next = *iphash_table_tail[bucket];
632                     *iphash_table_tail[bucket] = ic;
633                 }
634                 else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
635                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
636                             "VirtualHost %s:%u overlaps with "
637                             "VirtualHost %s:%u, the first has precedence, "
638                             "perhaps you need a NameVirtualHost directive",
639                             sar->virthost, sar->host_port,
640                             ic->sar->virthost, ic->sar->host_port);
641                     ic->sar = sar;
642                     ic->server = s;
643                 }
644             }
645         }
646
647         /* Ok now we want to set up a server_hostname if the user was
648          * silly enough to forget one.
649          * XXX: This is silly we should just crash and burn.
650          */
651         if (!s->server_hostname) {
652             if (has_default_vhost_addr) {
653                 s->server_hostname = main_s->server_hostname;
654             }
655             else if (!s->addrs) {
656                 /* what else can we do?  at this point this vhost has
657                     no configured name, probably because they used
658                     DNS in the VirtualHost statement.  It's disabled
659                     anyhow by the host matching code.  -djg */
660                 s->server_hostname =
661                     apr_pstrdup(p, "bogus_host_without_forward_dns");
662             }
663             else {
664                 apr_status_t rv;
665                 char *hostname;
666
667                 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
668                 if (rv == APR_SUCCESS) {
669                     s->server_hostname = apr_pstrdup(p, hostname);
670                 }
671                 else {
672                     /* again, what can we do?  They didn't specify a
673                        ServerName, and their DNS isn't working. -djg */
674                     char *ipaddr_str;
675
676                     apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
677                     ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
678                                  "Failed to resolve server name "
679                                  "for %s (check DNS) -- or specify an explicit "
680                                  "ServerName",
681                                  ipaddr_str);
682                     s->server_hostname =
683                         apr_pstrdup(p, "bogus_host_without_reverse_dns");
684                 }
685             }
686         }
687     }
688
689     /* now go through and delete any NameVirtualHosts that didn't have any
690      * hosts associated with them.  Lamers.
691      */
692     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
693         remove_unused_name_vhosts(main_s, &iphash_table[i]);
694     }
695     remove_unused_name_vhosts(main_s, &default_list);
696
697 #ifdef IPHASH_STATISTICS
698     dump_iphash_statistics(main_s);
699 #endif
700     if (ap_exists_config_define("DUMP_VHOSTS")) {
701         apr_file_t *thefile = NULL;
702         apr_file_open_stderr(&thefile, p);
703         dump_vhost_config(thefile);
704     }
705 }
706
707
708 /*****************************************************************************
709  * run-time vhost matching functions
710  */
711
712 /* Lowercase and remove any trailing dot and/or :port from the hostname,
713  * and check that it is sane.
714  *
715  * In most configurations the exact syntax of the hostname isn't
716  * important so strict sanity checking isn't necessary. However, in
717  * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
718  * the hostname is interpolated into the filename, we need to be sure
719  * that the interpolation doesn't expose parts of the filesystem.
720  * We don't do strict RFC 952 / RFC 1123 syntax checking in order
721  * to support iDNS and people who erroneously use underscores.
722  * Instead we just check for filesystem metacharacters: directory
723  * separators / and \ and sequences of more than one dot.
724  */
725 static void fix_hostname(request_rec *r)
726 {
727     char *host, *scope_id;
728     char *dst;
729     apr_port_t port;
730     apr_status_t rv;
731
732     rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
733     if (rv != APR_SUCCESS || scope_id) {
734         goto bad;
735     }
736
737     if (!host && port) {
738         /* silly looking host ("Host: 123") but that isn't our job
739          * here to judge; apr_parse_addr_port() would think we had a port
740          * but no address
741          */
742         host = apr_psprintf(r->pool, "%d", (int)port);
743     }
744
745     /* if the hostname is an IPv6 numeric address string, it was validated 
746      * already; otherwise, further validation is needed 
747      */
748     if (r->hostname[0] != '[') {
749         for (dst = host; *dst; dst++) {
750             if (*dst == '.') {
751                 dst++;
752                 if (*dst == '.')
753                     goto bad;
754             }
755             else if (*dst == '/' || *dst == '\\') {
756                 goto bad;
757             }
758         }
759         /* strip trailing gubbins */
760         if (dst > host && dst[-1] == '.') {
761             dst[-1] = '\0';
762         }
763     }
764     r->hostname = host;
765     return;
766
767 bad:
768     r->status = HTTP_BAD_REQUEST;
769     ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
770                   "Client sent malformed Host header");
771     return;
772 }
773
774
775 /* return 1 if host matches ServerName or ServerAliases */
776 static int matches_aliases(server_rec *s, const char *host)
777 {
778     int i;
779     apr_array_header_t *names;
780
781     /* match ServerName */
782     if (!strcasecmp(host, s->server_hostname)) {
783         return 1;
784     }
785
786     /* search all the aliases from ServerAlias directive */
787     names = s->names;
788     if (names) {
789         char **name = (char **) names->elts;
790         for (i = 0; i < names->nelts; ++i) {
791             if(!name[i]) continue;
792             if (!strcasecmp(host, name[i]))
793                 return 1;
794         }
795     }
796     names = s->wild_names;
797     if (names) {
798         char **name = (char **) names->elts;
799         for (i = 0; i < names->nelts; ++i) {
800             if(!name[i]) continue;
801             if (!ap_strcasecmp_match(host, name[i]))
802                 return 1;
803         }
804     }
805     return 0;
806 }
807
808
809 /* Suppose a request came in on the same socket as this r, and included
810  * a header "Host: host:port", would it map to r->server?  It's more
811  * than just that though.  When we do the normal matches for each request
812  * we don't even bother considering Host: etc on non-namevirtualhosts,
813  * we just call it a match.  But here we require the host:port to match
814  * the ServerName and/or ServerAliases.
815  */
816 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
817     apr_port_t port)
818 {
819     server_rec *s;
820     server_addr_rec *sar;
821
822     s = r->server;
823
824     /* search all the <VirtualHost> values */
825     /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
826      * consider: 
827      *
828      *     NameVirtualHost 10.1.1.1
829      *     <VirtualHost 10.1.1.1>
830      *     ServerName v1
831      *     </VirtualHost>
832      *     <VirtualHost 10.1.1.1>
833      *     ServerName v2
834      *     </VirtualHost>
835      *
836      * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll say
837      * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
838      * it would really go to v1.
839      */
840     for (sar = s->addrs; sar; sar = sar->next) {
841         if ((sar->host_port == 0 || port == sar->host_port)
842             && !strcasecmp(host, sar->virthost)) {
843             return 1;
844         }
845     }
846
847     /* the Port has to match now, because the rest don't have ports associated
848      * with them. */
849     if (port != s->port) {
850         return 0;
851     }
852
853     return matches_aliases(s, host);
854 }
855
856
857 static void check_hostalias(request_rec *r)
858 {
859     /*
860      * Even if the request has a Host: header containing a port we ignore
861      * that port.  We always use the physical port of the socket.  There
862      * are a few reasons for this:
863      *
864      * - the default of 80 or 443 for SSL is easier to handle this way
865      * - there is less of a possibility of a security problem
866      * - it simplifies the data structure
867      * - the client may have no idea that a proxy somewhere along the way
868      *   translated the request to another ip:port
869      * - except for the addresses from the VirtualHost line, none of the other
870      *   names we'll match have ports associated with them
871      */
872     const char *host = r->hostname;
873     apr_port_t port;
874     server_rec *s;
875     server_rec *last_s;
876     name_chain *src;
877     apr_sockaddr_t *localsa;
878
879     last_s = NULL;
880     apr_socket_addr_get(&localsa, APR_LOCAL, r->connection->client_socket);
881     apr_sockaddr_port_get(&port, localsa);
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         /* does it match the virthost from the sar? */
906         if (!strcasecmp(host, sar->virthost)) {
907             goto found;
908         }
909
910         if (s == last_s) {
911             /* we've already done ServerName and ServerAlias checks for this
912              * vhost
913              */
914             continue;
915         }
916         last_s = s;
917
918         if (matches_aliases(s, host)) {
919             goto found;
920         }
921     }
922     return;
923
924 found:
925     /* s is the first matching server, we're done */
926     r->server = s;
927 }
928
929
930 static void check_serverpath(request_rec *r)
931 {
932     server_rec *s;
933     server_rec *last_s;
934     name_chain *src;
935     apr_port_t port;
936     apr_sockaddr_t *localsa;
937
938     apr_socket_addr_get(&localsa, APR_LOCAL, r->connection->client_socket);
939     apr_sockaddr_port_get(&port, localsa);
940    
941     /*
942      * This is in conjunction with the ServerPath code in http_core, so we
943      * get the right host attached to a non- Host-sending request.
944      *
945      * See the comment in check_hostalias about how each vhost can be
946      * listed multiple times.
947      */
948
949     last_s = NULL;
950     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
951         /* We only consider addresses on the name_chain which have a matching
952          * port
953          */
954         if (src->sar->host_port != 0 && port != src->sar->host_port) {
955             continue;
956         }
957
958         s = src->server;
959         if (s == last_s) {
960             continue;
961         }
962         last_s = s;
963
964         if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
965             (s->path[s->pathlen - 1] == '/' ||
966              r->uri[s->pathlen] == '/' ||
967              r->uri[s->pathlen] == '\0')) {
968             r->server = s;
969             return;
970         }
971     }
972 }
973
974
975 void ap_update_vhost_from_headers(request_rec *r)
976 {
977     /* must set this for HTTP/1.1 support */
978     if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
979         fix_hostname(r);
980         if (r->status != HTTP_OK)
981             return;
982     }
983     /* check if we tucked away a name_chain */
984     if (r->connection->vhost_lookup_data) {
985         if (r->hostname)
986             check_hostalias(r);
987         else
988             check_serverpath(r);
989     }
990 }
991
992
993 /* Called for a new connection which has a known local_addr.  Note that the
994  * new connection is assumed to have conn->server == main server.
995  */
996 void ap_update_vhost_given_ip(conn_rec *conn)
997 {
998     ipaddr_chain *trav;
999     apr_port_t port;
1000
1001     /* scan the hash apr_table_t for an exact match first */
1002     trav = find_ipaddr(conn->local_addr);
1003     if (trav) {
1004         /* save the name_chain for later in case this is a name-vhost */
1005         conn->vhost_lookup_data = trav->names;
1006         conn->base_server = trav->server;
1007         return;
1008     }
1009
1010     /* maybe there's a default server or wildcard name-based vhost
1011      * matching this port
1012      */
1013     apr_sockaddr_port_get(&port, conn->local_addr);
1014     trav = find_default_server(port);
1015     if (trav) {
1016         conn->vhost_lookup_data = trav->names;
1017         conn->base_server = trav->server;
1018         return;
1019     }
1020
1021     /* otherwise we're stuck with just the main server
1022      * and no name-based vhosts
1023      */
1024     conn->vhost_lookup_data = NULL;
1025 }