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