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