]> granicus.if.org Git - apache/blob - server/vhost.c
mod_session_cookie: Add a session implementation capable of storing
[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 #define CORE_PRIVATE
31 #include "ap_config.h"
32 #include "httpd.h"
33 #include "http_config.h"
34 #include "http_log.h"
35 #include "http_vhost.h"
36 #include "http_protocol.h"
37 #include "http_core.h"
38
39 #if APR_HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
41 #endif
42
43 /*
44  * After all the definitions there's an explanation of how it's all put
45  * together.
46  */
47
48 /* meta-list of name-vhosts.  Each server_rec can be in possibly multiple
49  * lists of name-vhosts.
50  */
51 typedef struct name_chain name_chain;
52 struct name_chain {
53     name_chain *next;
54     server_addr_rec *sar;       /* the record causing it to be in
55                                  * this chain (needed for port comparisons) */
56     server_rec *server;         /* the server to use on a match */
57 };
58
59 /* meta-list of ip addresses.  Each server_rec can be in possibly multiple
60  * hash chains since it can have multiple ips.
61  */
62 typedef struct ipaddr_chain ipaddr_chain;
63 struct ipaddr_chain {
64     ipaddr_chain *next;
65     server_addr_rec *sar;       /* the record causing it to be in
66                                  * this chain (need for both ip addr and port
67                                  * comparisons) */
68     server_rec *server;         /* the server to use if this matches */
69     name_chain *names;          /* if non-NULL then a list of name-vhosts
70                                  * sharing this address */
71 };
72
73 /* This defines the size of the hash table used for hashing ip addresses
74  * of virtual hosts.  It must be a power of two.
75  */
76 #ifndef IPHASH_TABLE_SIZE
77 #define IPHASH_TABLE_SIZE 256
78 #endif
79
80 /* A (n) bucket hash table, each entry has a pointer to a server rec and
81  * a pointer to the other entries in that bucket.  Each individual address,
82  * even for virtualhosts with multiple addresses, has an entry in this hash
83  * table.  There are extra buckets for _default_, and name-vhost entries.
84  *
85  * Note that after config time this is constant, so it is thread-safe.
86  */
87 static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
88
89 /* dump out statistics about the hash function */
90 /* #define IPHASH_STATISTICS */
91
92 /* list of the _default_ servers */
93 static ipaddr_chain *default_list;
94
95 /* list of the NameVirtualHost addresses */
96 static server_addr_rec *name_vhost_list;
97 static server_addr_rec **name_vhost_list_tail;
98
99 /*
100  * How it's used:
101  *
102  * The ip address determines which chain in iphash_table is interesting, then
103  * a comparison is done down that chain to find the first ipaddr_chain whose
104  * sar matches the address:port pair.
105  *
106  * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
107  *
108  * Otherwise it's a name-vhost list, and the default is the server in the
109  * ipaddr_chain record.  We tuck away the ipaddr_chain record in the
110  * conn_rec field vhost_lookup_data.  Later on after the headers we get a
111  * second chance, and we use the name_chain to figure out what name-vhost
112  * matches the headers.
113  *
114  * If there was no ip address match in the iphash_table then do a lookup
115  * in the default_list.
116  *
117  * How it's put together ... well you should be able to figure that out
118  * from how it's used.  Or something like that.
119  */
120
121
122 /* called at the beginning of the config */
123 AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
124 {
125     memset(iphash_table, 0, sizeof(iphash_table));
126     default_list = NULL;
127     name_vhost_list = NULL;
128     name_vhost_list_tail = &name_vhost_list;
129 }
130
131
132 /*
133  * Parses a host of the form <address>[:port]
134  * paddr is used to create a list in the order of input
135  * **paddr is the ->next pointer of the last entry (or s->addrs)
136  * *paddr is the variable used to keep track of **paddr between calls
137  * port is the default port to assume
138  */
139 static const char *get_addresses(apr_pool_t *p, const char *w_,
140                                  server_addr_rec ***paddr,
141                                  apr_port_t default_port)
142 {
143     apr_sockaddr_t *my_addr;
144     server_addr_rec *sar;
145     char *w, *host, *scope_id;
146     int wild_port;
147     apr_size_t wlen;
148     apr_port_t port;
149     apr_status_t rv;
150
151     if (*w_ == '\0')
152         return NULL;
153
154     w = apr_pstrdup(p, w_);
155     /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
156     wlen = strlen(w);                    /* wlen must be > 0 at this point */
157     wild_port = 0;
158     if (w[wlen - 1] == '*') {
159         if (wlen < 2) {
160             wild_port = 1;
161         }
162         else if (w[wlen - 2] == ':') {
163             w[wlen - 2] = '\0';
164             wild_port = 1;
165         }
166     }
167     rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
168     /* If the string is "80", apr_parse_addr_port() will be happy and set
169      * host to NULL and port to 80, so watch out for that.
170      */
171     if (rv != APR_SUCCESS) {
172         return "The address or port is invalid";
173     }
174     if (!host) {
175         return "Missing address for VirtualHost";
176     }
177     if (scope_id) {
178         return "Scope ids are not supported";
179     }
180     if (!port && !wild_port) {
181         port = default_port;
182     }
183
184     if (strcmp(host, "*") == 0) {
185         rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p);
186         if (rv) {
187             return "Could not resolve address '0.0.0.0' -- "
188                 "check resolver configuration.";
189         }
190     }
191     else if (strcasecmp(host, "_default_") == 0
192         || strcmp(host, "255.255.255.255") == 0) {
193         rv = apr_sockaddr_info_get(&my_addr, "255.255.255.255", APR_INET, port, 0, p);
194         if (rv) {
195             return "Could not resolve address '255.255.255.255' -- "
196                 "check resolver configuration.";
197         }
198     }
199     else {
200         rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
201         if (rv != APR_SUCCESS) {
202             ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
203                 "Could not resolve host name %s -- ignoring!", host);
204             return NULL;
205         }
206     }
207
208     /* Remember all addresses for the host */
209
210     do {
211         sar = apr_pcalloc(p, sizeof(server_addr_rec));
212         **paddr = sar;
213         *paddr = &sar->next;
214         sar->host_addr = my_addr;
215         sar->host_port = port;
216         sar->virthost = host;
217         my_addr = my_addr->next;
218     } while (my_addr);
219
220     return NULL;
221 }
222
223
224 /* parse the <VirtualHost> addresses */
225 const char *ap_parse_vhost_addrs(apr_pool_t *p,
226                                  const char *hostname,
227                                  server_rec *s)
228 {
229     server_addr_rec **addrs;
230     const char *err;
231
232     /* start the list of addreses */
233     addrs = &s->addrs;
234     while (hostname[0]) {
235         err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
236         if (err) {
237             *addrs = NULL;
238             return err;
239         }
240     }
241     /* terminate the list */
242     *addrs = NULL;
243     if (s->addrs) {
244         if (s->addrs->host_port) {
245             /* override the default port which is inherited from main_server */
246             s->port = s->addrs->host_port;
247         }
248     }
249     return NULL;
250 }
251
252
253 const char *ap_set_name_virtual_host(cmd_parms *cmd, 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_stderr(&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
710     /* According to RFC 2616, Host header field CAN be blank. */
711     if (!*r->hostname) {
712         return;
713     }
714
715     rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
716     if (rv != APR_SUCCESS || scope_id) {
717         goto bad;
718     }
719
720     if (!host && port) {
721         /* silly looking host ("Host: 123") but that isn't our job
722          * here to judge; apr_parse_addr_port() would think we had a port
723          * but no address
724          */
725         host = apr_itoa(r->pool, (int)port);
726     }
727     else if (port) {
728         /* Don't throw the Host: header's port number away:
729            save it in parsed_uri -- ap_get_server_port() needs it! */
730         /* @@@ XXX there should be a better way to pass the port.
731          *         Like r->hostname, there should be a r->portno
732          */
733         r->parsed_uri.port = port;
734         r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
735     }
736
737     /* if the hostname is an IPv6 numeric address string, it was validated
738      * already; otherwise, further validation is needed
739      */
740     if (r->hostname[0] != '[') {
741         for (dst = host; *dst; dst++) {
742             if (apr_islower(*dst)) {
743                 /* leave char unchanged */
744             }
745             else if (*dst == '.') {
746                 if (*(dst + 1) == '.') {
747                     goto bad;
748                 }
749             }
750             else if (apr_isupper(*dst)) {
751                 *dst = apr_tolower(*dst);
752             }
753             else if (*dst == '/' || *dst == '\\') {
754                 goto bad;
755             }
756         }
757         /* strip trailing gubbins */
758         if (dst > host && dst[-1] == '.') {
759             dst[-1] = '\0';
760         }
761     }
762     r->hostname = host;
763     return;
764
765 bad:
766     r->status = HTTP_BAD_REQUEST;
767     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
768                   "Client sent malformed Host header");
769     return;
770 }
771
772
773 /* return 1 if host matches ServerName or ServerAliases */
774 static int matches_aliases(server_rec *s, const char *host)
775 {
776     int i;
777     apr_array_header_t *names;
778
779     /* match ServerName */
780     if (!strcasecmp(host, s->server_hostname)) {
781         return 1;
782     }
783
784     /* search all the aliases from ServerAlias directive */
785     names = s->names;
786     if (names) {
787         char **name = (char **) names->elts;
788         for (i = 0; i < names->nelts; ++i) {
789             if(!name[i]) continue;
790             if (!strcasecmp(host, name[i]))
791                 return 1;
792         }
793     }
794     names = s->wild_names;
795     if (names) {
796         char **name = (char **) names->elts;
797         for (i = 0; i < names->nelts; ++i) {
798             if(!name[i]) continue;
799             if (!ap_strcasecmp_match(host, name[i]))
800                 return 1;
801         }
802     }
803     return 0;
804 }
805
806
807 /* Suppose a request came in on the same socket as this r, and included
808  * a header "Host: host:port", would it map to r->server?  It's more
809  * than just that though.  When we do the normal matches for each request
810  * we don't even bother considering Host: etc on non-namevirtualhosts,
811  * we just call it a match.  But here we require the host:port to match
812  * the ServerName and/or ServerAliases.
813  */
814 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
815                                          apr_port_t port)
816 {
817     server_rec *s;
818     server_addr_rec *sar;
819
820     s = r->server;
821
822     /* search all the <VirtualHost> values */
823     /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
824      * consider:
825      *
826      *     NameVirtualHost 10.1.1.1
827      *     <VirtualHost 10.1.1.1>
828      *     ServerName v1
829      *     </VirtualHost>
830      *     <VirtualHost 10.1.1.1>
831      *     ServerName v2
832      *     </VirtualHost>
833      *
834      * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll say
835      * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
836      * it would really go to v1.
837      */
838     for (sar = s->addrs; sar; sar = sar->next) {
839         if ((sar->host_port == 0 || port == sar->host_port)
840             && !strcasecmp(host, sar->virthost)) {
841             return 1;
842         }
843     }
844
845     /* the Port has to match now, because the rest don't have ports associated
846      * with them. */
847     if (port != s->port) {
848         return 0;
849     }
850
851     return matches_aliases(s, host);
852 }
853
854
855 static void check_hostalias(request_rec *r)
856 {
857     /*
858      * Even if the request has a Host: header containing a port we ignore
859      * that port.  We always use the physical port of the socket.  There
860      * are a few reasons for this:
861      *
862      * - the default of 80 or 443 for SSL is easier to handle this way
863      * - there is less of a possibility of a security problem
864      * - it simplifies the data structure
865      * - the client may have no idea that a proxy somewhere along the way
866      *   translated the request to another ip:port
867      * - except for the addresses from the VirtualHost line, none of the other
868      *   names we'll match have ports associated with them
869      */
870     const char *host = r->hostname;
871     apr_port_t port;
872     server_rec *s;
873     server_rec *last_s;
874     name_chain *src;
875
876     last_s = NULL;
877
878     port = r->connection->local_addr->port;
879
880     /* Recall that the name_chain is a list of server_addr_recs, some of
881      * whose ports may not match.  Also each server may appear more than
882      * once in the chain -- specifically, it will appear once for each
883      * address from its VirtualHost line which matched.  We only want to
884      * do the full ServerName/ServerAlias comparisons once for each
885      * server, fortunately we know that all the VirtualHost addresses for
886      * a single server are adjacent to each other.
887      */
888
889     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
890         server_addr_rec *sar;
891
892         /* We only consider addresses on the name_chain which have a matching
893          * port
894          */
895         sar = src->sar;
896         if (sar->host_port != 0 && port != sar->host_port) {
897             continue;
898         }
899
900         s = src->server;
901
902         /* does it match the virthost from the sar? */
903         if (!strcasecmp(host, sar->virthost)) {
904             goto found;
905         }
906
907         if (s == last_s) {
908             /* we've already done ServerName and ServerAlias checks for this
909              * vhost
910              */
911             continue;
912         }
913         last_s = s;
914
915         if (matches_aliases(s, host)) {
916             goto found;
917         }
918     }
919     return;
920
921 found:
922     /* s is the first matching server, we're done */
923     r->server = s;
924 }
925
926
927 static void check_serverpath(request_rec *r)
928 {
929     server_rec *s;
930     server_rec *last_s;
931     name_chain *src;
932     apr_port_t port;
933
934     port = r->connection->local_addr->port;
935
936     /*
937      * This is in conjunction with the ServerPath code in http_core, so we
938      * get the right host attached to a non- Host-sending request.
939      *
940      * See the comment in check_hostalias about how each vhost can be
941      * listed multiple times.
942      */
943
944     last_s = NULL;
945     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
946         /* We only consider addresses on the name_chain which have a matching
947          * port
948          */
949         if (src->sar->host_port != 0 && port != src->sar->host_port) {
950             continue;
951         }
952
953         s = src->server;
954         if (s == last_s) {
955             continue;
956         }
957         last_s = s;
958
959         if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
960             (s->path[s->pathlen - 1] == '/' ||
961              r->uri[s->pathlen] == '/' ||
962              r->uri[s->pathlen] == '\0')) {
963             r->server = s;
964             return;
965         }
966     }
967 }
968
969
970 AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
971 {
972     /* must set this for HTTP/1.1 support */
973     if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
974         fix_hostname(r);
975         if (r->status != HTTP_OK)
976             return;
977     }
978     /* check if we tucked away a name_chain */
979     if (r->connection->vhost_lookup_data) {
980         if (r->hostname)
981             check_hostalias(r);
982         else
983             check_serverpath(r);
984     }
985 }
986
987 /**
988  * For every virtual host on this connection, call func_cb.
989  */
990 AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
991                                             ap_vhost_iterate_conn_cb func_cb,
992                                             void* baton)
993 {
994     server_rec *s;
995     server_rec *last_s;
996     name_chain *src;
997     apr_port_t port;
998     int rv = 0;
999
1000     if (conn->vhost_lookup_data) {
1001         last_s = NULL;
1002         port = conn->local_addr->port;
1003
1004         for (src = conn->vhost_lookup_data; src; src = src->next) {
1005             server_addr_rec *sar;
1006
1007             /* We only consider addresses on the name_chain which have a
1008              * matching port.
1009              */
1010             sar = src->sar;
1011             if (sar->host_port != 0 && port != sar->host_port) {
1012                 continue;
1013             }
1014
1015             s = src->server;
1016
1017             if (s == last_s) {
1018                 /* we've already done a callback for this vhost. */
1019                 continue;
1020             }
1021
1022             last_s = s;
1023
1024             rv = func_cb(baton, conn, s);
1025
1026             if (rv != 0) {
1027                 break;
1028             }
1029         }
1030     }
1031     else {
1032         rv = func_cb(baton, conn, conn->base_server);
1033     }
1034
1035     return rv;
1036 }
1037
1038 /* Called for a new connection which has a known local_addr.  Note that the
1039  * new connection is assumed to have conn->server == main server.
1040  */
1041 AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
1042 {
1043     ipaddr_chain *trav;
1044     apr_port_t port;
1045
1046     /* scan the hash table for an exact match first */
1047     trav = find_ipaddr(conn->local_addr);
1048
1049     if (trav) {
1050         /* save the name_chain for later in case this is a name-vhost */
1051         conn->vhost_lookup_data = trav->names;
1052         conn->base_server = trav->server;
1053         return;
1054     }
1055
1056     /* maybe there's a default server or wildcard name-based vhost
1057      * matching this port
1058      */
1059     port = conn->local_addr->port;
1060
1061     trav = find_default_server(port);
1062     if (trav) {
1063         conn->vhost_lookup_data = trav->names;
1064         conn->base_server = trav->server;
1065         return;
1066     }
1067
1068     /* otherwise we're stuck with just the main server
1069      * and no name-based vhosts
1070      */
1071     conn->vhost_lookup_data = NULL;
1072 }