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