]> granicus.if.org Git - apache/blob - server/vhost.c
fix references / update transformation
[apache] / server / vhost.c
1 /* Copyright 1999-2004 The 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 table 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 table 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 table 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 {
504             pic = &ic->next;
505         }
506     }
507 }
508
509 /* compile the tables and such we need to do the run-time vhost lookups */
510 AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
511 {
512     server_addr_rec *sar;
513     int has_default_vhost_addr;
514     server_rec *s;
515     int i;
516     ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
517
518     /* terminate the name_vhost list */
519     *name_vhost_list_tail = NULL;
520
521     /* Main host first */
522     s = main_s;
523
524     if (!s->server_hostname) {
525         s->server_hostname = ap_get_local_host(p);
526     }
527
528     /* initialize the tails */
529     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
530         iphash_table_tail[i] = &iphash_table[i];
531     }
532
533     /* The first things to go into the hash table are the NameVirtualHosts
534      * Since name_vhost_list is in the same order that the directives
535      * occured in the config file, we'll copy it in that order.
536      */
537     for (sar = name_vhost_list; sar; sar = sar->next) {
538         char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
539         unsigned bucket = hash_addr(sar->host_addr);
540         ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
541
542         if (memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, 
543                    sar->host_addr->ipaddr_len)) { /* not IN[6]ADDR_ANY */
544             *iphash_table_tail[bucket] = ic;
545             iphash_table_tail[bucket] = &ic->next;
546         }
547         else {
548             /* A wildcard NameVirtualHost goes on the default_list so
549              * that it can catch incoming requests on any address.
550              */
551             ic->next = default_list;
552             default_list = ic;
553         }
554         /* Notice that what we've done is insert an ipaddr_chain with
555          * both server and names NULL. This fact is used to spot name-
556          * based vhosts in add_name_vhost_config().
557          */
558     }
559
560     /* The next things to go into the hash table are the virtual hosts
561      * themselves.  They're listed off of main_s->next in the reverse
562      * order they occured in the config file, so we insert them at
563      * the iphash_table_tail but don't advance the tail.
564      */
565
566     for (s = main_s->next; s; s = s->next) {
567         has_default_vhost_addr = 0;
568         for (sar = s->addrs; sar; sar = sar->next) {
569             ipaddr_chain *ic;
570             char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
571
572             if ((sar->host_addr->family == AF_INET &&
573                  sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR)
574                 || !memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
575                 ic = find_default_server(sar->host_port);
576                 if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
577                     if (ic && ic->sar->host_port != 0) {
578                         ap_log_error(APLOG_MARK, APLOG_WARNING,
579                                      0, main_s, "_default_ VirtualHost "
580                                      "overlap on port %u, the first has "
581                                      "precedence", sar->host_port);
582                     }
583                     ic = new_ipaddr_chain(p, s, sar);
584                     ic->next = default_list;
585                     default_list = ic;
586                 }
587                 has_default_vhost_addr = 1;
588             }
589             else {
590                 /* see if it matches something we've already got */
591                 ic = find_ipaddr(sar->host_addr);
592
593                 if (!ic) {
594                     unsigned bucket = hash_addr(sar->host_addr);
595
596                     ic = new_ipaddr_chain(p, s, sar);
597                     ic->next = *iphash_table_tail[bucket];
598                     *iphash_table_tail[bucket] = ic;
599                 }
600                 else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
601                     ap_log_error(APLOG_MARK, APLOG_WARNING,
602                                  0, main_s, "VirtualHost %s:%u overlaps "
603                                  "with VirtualHost %s:%u, the first has "
604                                  "precedence, perhaps you need a "
605                                  "NameVirtualHost directive",
606                                  sar->virthost, sar->host_port,
607                                  ic->sar->virthost, ic->sar->host_port);
608                     ic->sar = sar;
609                     ic->server = s;
610                 }
611             }
612         }
613
614         /* Ok now we want to set up a server_hostname if the user was
615          * silly enough to forget one.
616          * XXX: This is silly we should just crash and burn.
617          */
618         if (!s->server_hostname) {
619             if (has_default_vhost_addr) {
620                 s->server_hostname = main_s->server_hostname;
621             }
622             else if (!s->addrs) {
623                 /* what else can we do?  at this point this vhost has
624                     no configured name, probably because they used
625                     DNS in the VirtualHost statement.  It's disabled
626                     anyhow by the host matching code.  -djg */
627                 s->server_hostname =
628                     apr_pstrdup(p, "bogus_host_without_forward_dns");
629             }
630             else {
631                 apr_status_t rv;
632                 char *hostname;
633
634                 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
635                 if (rv == APR_SUCCESS) {
636                     s->server_hostname = apr_pstrdup(p, hostname);
637                 }
638                 else {
639                     /* again, what can we do?  They didn't specify a
640                        ServerName, and their DNS isn't working. -djg */
641                     char *ipaddr_str;
642
643                     apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
644                     ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
645                                  "Failed to resolve server name "
646                                  "for %s (check DNS) -- or specify an explicit "
647                                  "ServerName",
648                                  ipaddr_str);
649                     s->server_hostname =
650                         apr_pstrdup(p, "bogus_host_without_reverse_dns");
651                 }
652             }
653         }
654     }
655
656     /* now go through and delete any NameVirtualHosts that didn't have any
657      * hosts associated with them.  Lamers.
658      */
659     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
660         remove_unused_name_vhosts(main_s, &iphash_table[i]);
661     }
662     remove_unused_name_vhosts(main_s, &default_list);
663
664 #ifdef IPHASH_STATISTICS
665     dump_iphash_statistics(main_s);
666 #endif
667     if (ap_exists_config_define("DUMP_VHOSTS")) {
668         apr_file_t *thefile = NULL;
669         apr_file_open_stderr(&thefile, p);
670         dump_vhost_config(thefile);
671     }
672 }
673
674
675 /*****************************************************************************
676  * run-time vhost matching functions
677  */
678
679 /* Lowercase and remove any trailing dot and/or :port from the hostname,
680  * and check that it is sane.
681  *
682  * In most configurations the exact syntax of the hostname isn't
683  * important so strict sanity checking isn't necessary. However, in
684  * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
685  * the hostname is interpolated into the filename, we need to be sure
686  * that the interpolation doesn't expose parts of the filesystem.
687  * We don't do strict RFC 952 / RFC 1123 syntax checking in order
688  * to support iDNS and people who erroneously use underscores.
689  * Instead we just check for filesystem metacharacters: directory
690  * separators / and \ and sequences of more than one dot.
691  */
692 static void fix_hostname(request_rec *r)
693 {
694     char *host, *scope_id;
695     char *dst;
696     apr_port_t port;
697     apr_status_t rv;
698
699     /* According to RFC 2616, Host header field CAN be blank. */
700     if (!*r->hostname) {
701         return;
702     }
703
704     rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
705     if (rv != APR_SUCCESS || scope_id) {
706         goto bad;
707     }
708
709     if (!host && port) {
710         /* silly looking host ("Host: 123") but that isn't our job
711          * here to judge; apr_parse_addr_port() would think we had a port
712          * but no address
713          */
714         host = apr_itoa(r->pool, (int)port);
715     }
716     else if (port) {
717         /* Don't throw the Host: header's port number away:
718            save it in parsed_uri -- ap_get_server_port() needs it! */
719         /* @@@ XXX there should be a better way to pass the port.
720          *         Like r->hostname, there should be a r->portno
721          */
722         r->parsed_uri.port = port;
723         r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
724     }
725
726     /* if the hostname is an IPv6 numeric address string, it was validated 
727      * already; otherwise, further validation is needed 
728      */
729     if (r->hostname[0] != '[') {
730         for (dst = host; *dst; dst++) {
731             if (apr_islower(*dst)) {
732                 /* leave char unchanged */
733             }
734             else if (*dst == '.') {
735                 if (*(dst + 1) == '.') {
736                     goto bad;
737                 }
738             }
739             else if (apr_isupper(*dst)) {
740                 *dst = apr_tolower(*dst);
741             }
742             else if (*dst == '/' || *dst == '\\') {
743                 goto bad;
744             }
745         }
746         /* strip trailing gubbins */
747         if (dst > host && dst[-1] == '.') {
748             dst[-1] = '\0';
749         }
750     }
751     r->hostname = host;
752     return;
753
754 bad:
755     r->status = HTTP_BAD_REQUEST;
756     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
757                   "Client sent malformed Host header");
758     return;
759 }
760
761
762 /* return 1 if host matches ServerName or ServerAliases */
763 static int matches_aliases(server_rec *s, const char *host)
764 {
765     int i;
766     apr_array_header_t *names;
767
768     /* match ServerName */
769     if (!strcasecmp(host, s->server_hostname)) {
770         return 1;
771     }
772
773     /* search all the aliases from ServerAlias directive */
774     names = s->names;
775     if (names) {
776         char **name = (char **) names->elts;
777         for (i = 0; i < names->nelts; ++i) {
778             if(!name[i]) continue;
779             if (!strcasecmp(host, name[i]))
780                 return 1;
781         }
782     }
783     names = s->wild_names;
784     if (names) {
785         char **name = (char **) names->elts;
786         for (i = 0; i < names->nelts; ++i) {
787             if(!name[i]) continue;
788             if (!ap_strcasecmp_match(host, name[i]))
789                 return 1;
790         }
791     }
792     return 0;
793 }
794
795
796 /* Suppose a request came in on the same socket as this r, and included
797  * a header "Host: host:port", would it map to r->server?  It's more
798  * than just that though.  When we do the normal matches for each request
799  * we don't even bother considering Host: etc on non-namevirtualhosts,
800  * we just call it a match.  But here we require the host:port to match
801  * the ServerName and/or ServerAliases.
802  */
803 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
804                                          apr_port_t port)
805 {
806     server_rec *s;
807     server_addr_rec *sar;
808
809     s = r->server;
810
811     /* search all the <VirtualHost> values */
812     /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
813      * consider: 
814      *
815      *     NameVirtualHost 10.1.1.1
816      *     <VirtualHost 10.1.1.1>
817      *     ServerName v1
818      *     </VirtualHost>
819      *     <VirtualHost 10.1.1.1>
820      *     ServerName v2
821      *     </VirtualHost>
822      *
823      * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll say
824      * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
825      * it would really go to v1.
826      */
827     for (sar = s->addrs; sar; sar = sar->next) {
828         if ((sar->host_port == 0 || port == sar->host_port)
829             && !strcasecmp(host, sar->virthost)) {
830             return 1;
831         }
832     }
833
834     /* the Port has to match now, because the rest don't have ports associated
835      * with them. */
836     if (port != s->port) {
837         return 0;
838     }
839
840     return matches_aliases(s, host);
841 }
842
843
844 static void check_hostalias(request_rec *r)
845 {
846     /*
847      * Even if the request has a Host: header containing a port we ignore
848      * that port.  We always use the physical port of the socket.  There
849      * are a few reasons for this:
850      *
851      * - the default of 80 or 443 for SSL is easier to handle this way
852      * - there is less of a possibility of a security problem
853      * - it simplifies the data structure
854      * - the client may have no idea that a proxy somewhere along the way
855      *   translated the request to another ip:port
856      * - except for the addresses from the VirtualHost line, none of the other
857      *   names we'll match have ports associated with them
858      */
859     const char *host = r->hostname;
860     apr_port_t port;
861     server_rec *s;
862     server_rec *last_s;
863     name_chain *src;
864
865     last_s = NULL;
866
867     port = r->connection->local_addr->port;
868
869     /* Recall that the name_chain is a list of server_addr_recs, some of
870      * whose ports may not match.  Also each server may appear more than
871      * once in the chain -- specifically, it will appear once for each
872      * address from its VirtualHost line which matched.  We only want to
873      * do the full ServerName/ServerAlias comparisons once for each
874      * server, fortunately we know that all the VirtualHost addresses for
875      * a single server are adjacent to each other.
876      */
877
878     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
879         server_addr_rec *sar;
880
881         /* We only consider addresses on the name_chain which have a matching
882          * port
883          */
884         sar = src->sar;
885         if (sar->host_port != 0 && port != sar->host_port) {
886             continue;
887         }
888
889         s = src->server;
890
891         /* does it match the virthost from the sar? */
892         if (!strcasecmp(host, sar->virthost)) {
893             goto found;
894         }
895
896         if (s == last_s) {
897             /* we've already done ServerName and ServerAlias checks for this
898              * vhost
899              */
900             continue;
901         }
902         last_s = s;
903
904         if (matches_aliases(s, host)) {
905             goto found;
906         }
907     }
908     return;
909
910 found:
911     /* s is the first matching server, we're done */
912     r->server = s;
913 }
914
915
916 static void check_serverpath(request_rec *r)
917 {
918     server_rec *s;
919     server_rec *last_s;
920     name_chain *src;
921     apr_port_t port;
922
923     port = r->connection->local_addr->port;
924
925     /*
926      * This is in conjunction with the ServerPath code in http_core, so we
927      * get the right host attached to a non- Host-sending request.
928      *
929      * See the comment in check_hostalias about how each vhost can be
930      * listed multiple times.
931      */
932
933     last_s = NULL;
934     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
935         /* We only consider addresses on the name_chain which have a matching
936          * port
937          */
938         if (src->sar->host_port != 0 && port != src->sar->host_port) {
939             continue;
940         }
941
942         s = src->server;
943         if (s == last_s) {
944             continue;
945         }
946         last_s = s;
947
948         if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
949             (s->path[s->pathlen - 1] == '/' ||
950              r->uri[s->pathlen] == '/' ||
951              r->uri[s->pathlen] == '\0')) {
952             r->server = s;
953             return;
954         }
955     }
956 }
957
958
959 AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
960 {
961     /* must set this for HTTP/1.1 support */
962     if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
963         fix_hostname(r);
964         if (r->status != HTTP_OK)
965             return;
966     }
967     /* check if we tucked away a name_chain */
968     if (r->connection->vhost_lookup_data) {
969         if (r->hostname)
970             check_hostalias(r);
971         else
972             check_serverpath(r);
973     }
974 }
975
976
977 /* Called for a new connection which has a known local_addr.  Note that the
978  * new connection is assumed to have conn->server == main server.
979  */
980 AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
981 {
982     ipaddr_chain *trav;
983     apr_port_t port;
984
985     /* scan the hash table for an exact match first */
986     trav = find_ipaddr(conn->local_addr);
987
988     if (trav) {
989         /* save the name_chain for later in case this is a name-vhost */
990         conn->vhost_lookup_data = trav->names;
991         conn->base_server = trav->server;
992         return;
993     }
994
995     /* maybe there's a default server or wildcard name-based vhost
996      * matching this port
997      */
998     port = conn->local_addr->port;
999
1000     trav = find_default_server(port);
1001     if (trav) {
1002         conn->vhost_lookup_data = trav->names;
1003         conn->base_server = trav->server;
1004         return;
1005     }
1006
1007     /* otherwise we're stuck with just the main server
1008      * and no name-based vhosts
1009      */
1010     conn->vhost_lookup_data = NULL;
1011 }