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