]> granicus.if.org Git - apache/blob - server/vhost.c
CGIs work again on UNIX because ap_create_process() works again on UNIX.
[apache] / server / vhost.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000 The Apache Software Foundation.  All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  *    if any, must include the following acknowledgment:
21  *       "This product includes software developed by the
22  *        Apache Software Foundation (http://www.apache.org/)."
23  *    Alternately, this acknowledgment may appear in the software itself,
24  *    if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  *    not be used to endorse or promote products derived from this
28  *    software without prior written permission. For written
29  *    permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  *    nor may "Apache" appear in their name, without prior written
33  *    permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation.  For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  *
54  * Portions of this software are based upon public domain software
55  * originally written at the National Center for Supercomputing Applications,
56  * University of Illinois, Urbana-Champaign.
57  */
58
59 /*
60  * http_vhost.c: functions pertaining to virtual host addresses
61  *      (configuration and run-time)
62  */
63
64 #define CORE_PRIVATE
65 #include "ap_config.h"
66 #include "httpd.h"
67 #include "http_config.h"
68 #include "http_log.h"
69 #include "http_vhost.h"
70 #include "http_protocol.h"
71 #include "http_core.h"
72
73 /*
74  * After all the definitions there's an explanation of how it's all put
75  * together.
76  */
77
78 /* meta-list of name-vhosts.  Each server_rec can be in possibly multiple
79  * lists of name-vhosts.
80  */
81 typedef struct name_chain name_chain;
82 struct name_chain {
83     name_chain *next;
84     server_addr_rec *sar;       /* the record causing it to be in
85                                  * this chain (needed for port comparisons) */
86     server_rec *server;         /* the server to use on a match */
87 };
88
89 /* meta-list of ip addresses.  Each server_rec can be in possibly multiple
90  * hash chains since it can have multiple ips.
91  */
92 typedef struct ipaddr_chain ipaddr_chain;
93 struct ipaddr_chain {
94     ipaddr_chain *next;
95     server_addr_rec *sar;       /* the record causing it to be in
96                                  * this chain (need for both ip addr and port
97                                  * comparisons) */
98     server_rec *server;         /* the server to use if this matches */
99     name_chain *names;          /* if non-NULL then a list of name-vhosts
100                                  * sharing this address */
101 };
102
103 /* This defines the size of the hash ap_table_t used for hashing ip addresses
104  * of virtual hosts.  It must be a power of two.
105  */
106 #ifndef IPHASH_TABLE_SIZE
107 #define IPHASH_TABLE_SIZE 256
108 #endif
109
110 /* A (n) bucket hash table, each entry has a pointer to a server rec and
111  * a pointer to the other entries in that bucket.  Each individual address,
112  * even for virtualhosts with multiple addresses, has an entry in this hash
113  * table.  There are extra buckets for _default_, and name-vhost entries.
114  *
115  * Note that after config time this is constant, so it is thread-safe.
116  */
117 static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
118
119 /* dump out statistics about the hash function */
120 /* #define IPHASH_STATISTICS */
121
122 /* list of the _default_ servers */
123 static ipaddr_chain *default_list;
124
125 /* list of the NameVirtualHost addresses */
126 static server_addr_rec *name_vhost_list;
127 static server_addr_rec **name_vhost_list_tail;
128
129 /*
130  * How it's used:
131  *
132  * The ip address determines which chain in iphash_table is interesting, then
133  * a comparison is done down that chain to find the first ipaddr_chain whose
134  * sar matches the address:port pair.
135  *
136  * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
137  *
138  * Otherwise it's a name-vhost list, and the default is the server in the
139  * ipaddr_chain record.  We tuck away the ipaddr_chain record in the
140  * conn_rec field vhost_lookup_data.  Later on after the headers we get a
141  * second chance, and we use the name_chain to figure out what name-vhost
142  * matches the headers.
143  *
144  * If there was no ip address match in the iphash_table then do a lookup
145  * in the default_list.
146  *
147  * How it's put together ... well you should be able to figure that out
148  * from how it's used.  Or something like that.
149  */
150
151
152 /* called at the beginning of the config */
153 void ap_init_vhost_config(ap_context_t *p)
154 {
155     memset(iphash_table, 0, sizeof(iphash_table));
156     default_list = NULL;
157     name_vhost_list = NULL;
158     name_vhost_list_tail = &name_vhost_list;
159 }
160
161
162 /*
163  * Parses a host of the form <address>[:port]
164  * paddr is used to create a list in the order of input
165  * **paddr is the ->next pointer of the last entry (or s->addrs)
166  * *paddr is the variable used to keep track of **paddr between calls
167  * port is the default port to assume
168  */
169 static const char *get_addresses(ap_context_t *p, char *w, server_addr_rec ***paddr,
170                             unsigned port)
171 {
172     struct hostent *hep;
173     unsigned long my_addr;
174     server_addr_rec *sar;
175     char *t;
176     int i, is_an_ip_addr;
177
178     if (*w == 0)
179         return NULL;
180
181     t = strchr(w, ':');
182     if (t) {
183         if (strcmp(t + 1, "*") == 0) {
184             port = 0;
185         }
186         else if ((i = atoi(t + 1))) {
187             port = i;
188         }
189         else {
190             return ":port must be numeric";
191         }
192         *t = 0;
193     }
194
195     is_an_ip_addr = 0;
196     if (strcmp(w, "*") == 0) {
197         my_addr = htonl(INADDR_ANY);
198         is_an_ip_addr = 1;
199     }
200     else if (strcasecmp(w, "_default_") == 0
201              || strcmp(w, "255.255.255.255") == 0) {
202         my_addr = DEFAULT_VHOST_ADDR;
203         is_an_ip_addr = 1;
204     }
205     else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
206         is_an_ip_addr = 1;
207     }
208     if (is_an_ip_addr) {
209         sar = ap_pcalloc(p, sizeof(server_addr_rec));
210         **paddr = sar;
211         *paddr = &sar->next;
212         sar->host_addr.s_addr = my_addr;
213         sar->host_port = port;
214         sar->virthost = ap_pstrdup(p, w);
215         if (t != NULL)
216             *t = ':';
217         return NULL;
218     }
219
220     hep = gethostbyname(w);
221
222     if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
223         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, NULL,
224             "Cannot resolve host name %s --- ignoring!", w);
225         if (t != NULL)
226             *t = ':';
227         return NULL;
228     }
229
230     for (i = 0; hep->h_addr_list[i]; ++i) {
231         sar = ap_pcalloc(p, sizeof(server_addr_rec));
232         **paddr = sar;
233         *paddr = &sar->next;
234         sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
235         sar->host_port = port;
236         sar->virthost = ap_pstrdup(p, w);
237     }
238
239     if (t != NULL)
240         *t = ':';
241     return NULL;
242 }
243
244
245 /* parse the <VirtualHost> addresses */
246 const char *ap_parse_vhost_addrs(ap_context_t *p, const char *hostname, server_rec *s)
247 {
248     server_addr_rec **addrs;
249     const char *err;
250
251     /* start the list of addreses */
252     addrs = &s->addrs;
253     while (hostname[0]) {
254         err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
255         if (err) {
256             *addrs = NULL;
257             return err;
258         }
259     }
260     /* terminate the list */
261     *addrs = NULL;
262     if (s->addrs) {
263         if (s->addrs->host_port) {
264             /* override the default port which is inherited from main_server */
265             s->port = s->addrs->host_port;
266         }
267     }
268     return NULL;
269 }
270
271
272 const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
273 {
274     /* use whatever port the main server has at this point */
275     return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
276                             cmd->server->port);
277 }
278
279
280 /* hash ap_table_t statistics, keep this in here for the beta period so
281  * we can find out if the hash function is ok
282  */
283 #ifdef IPHASH_STATISTICS
284 static int iphash_compare(const void *a, const void *b)
285 {
286     return (*(const int *) b - *(const int *) a);
287 }
288
289
290 static void dump_iphash_statistics(server_rec *main_s)
291 {
292     unsigned count[IPHASH_TABLE_SIZE];
293     int i;
294     ipaddr_chain *src;
295     unsigned total;
296     char buf[HUGE_STRING_LEN];
297     char *p;
298
299     total = 0;
300     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
301         count[i] = 0;
302         for (src = iphash_table[i]; src; src = src->next) {
303             ++count[i];
304             if (i < IPHASH_TABLE_SIZE) {
305                 /* don't count the slop buckets in the total */
306                 ++total;
307             }
308         }
309     }
310     qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
311     p = buf + ap_snprintf(buf, sizeof(buf),
312                     "iphash: total hashed = %u, avg chain = %u, "
313                     "chain lengths (count x len):",
314                     total, total / IPHASH_TABLE_SIZE);
315     total = 1;
316     for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
317         if (count[i - 1] != count[i]) {
318             p += ap_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
319                              total, count[i - 1]);
320             total = 1;
321         }
322         else {
323             ++total;
324         }
325     }
326     p += ap_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
327                      total, count[IPHASH_TABLE_SIZE - 1]);
328     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, main_s, buf);
329 }
330 #endif
331
332
333 /* This hashing function is designed to get good distribution in the cases
334  * where the server is handling entire "networks" of servers.  i.e. a
335  * whack of /24s.  This is probably the most common configuration for
336  * ISPs with large virtual servers.
337  *
338  * NOTE: This function is symmetric (i.e. collapses all 4 octets
339  * into one), so machine byte order (big/little endianness) does not matter.
340  *
341  * Hash function provided by David Hankins.
342  */
343 static ap_inline unsigned hash_inaddr(unsigned key)
344 {
345     key ^= (key >> 16);
346     return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
347 }
348
349
350
351 static ipaddr_chain *new_ipaddr_chain(ap_context_t *p,
352                                     server_rec *s, server_addr_rec *sar)
353 {
354     ipaddr_chain *new;
355
356     new = ap_palloc(p, sizeof(*new));
357     new->names = NULL;
358     new->server = s;
359     new->sar = sar;
360     new->next = NULL;
361     return new;
362 }
363
364
365 static name_chain *new_name_chain(ap_context_t *p, server_rec *s, server_addr_rec *sar)
366 {
367     name_chain *new;
368
369     new = ap_palloc(p, sizeof(*new));
370     new->server = s;
371     new->sar = sar;
372     new->next = NULL;
373     return new;
374 }
375
376
377 static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
378     unsigned port)
379 {
380     unsigned bucket;
381     ipaddr_chain *trav;
382     unsigned addr;
383
384     /* scan the hash ap_table_t for an exact match first */
385     addr = server_ip->s_addr;
386     bucket = hash_inaddr(addr);
387     for (trav = iphash_table[bucket]; trav; trav = trav->next) {
388         server_addr_rec *sar = trav->sar;
389         if ((sar->host_addr.s_addr == addr)
390             && (sar->host_port == 0 || sar->host_port == port
391                 || port == 0)) {
392             return trav;
393         }
394     }
395     return NULL;
396 }
397
398
399 static ipaddr_chain *find_default_server(unsigned port)
400 {
401     server_addr_rec *sar;
402     ipaddr_chain *trav;
403
404     for (trav = default_list; trav; trav = trav->next) {
405         sar = trav->sar;
406         if (sar->host_port == 0 || sar->host_port == port) {
407             /* match! */
408             return trav;
409         }
410     }
411     return NULL;
412 }
413
414 static void dump_vhost_config(ap_file_t *f)
415 {
416     int i;
417     ipaddr_chain *ic;
418     name_chain *nc;
419     char buf[MAX_STRING_LEN];
420
421     ap_fprintf(f, "VirtualHost configuration:\n");
422     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
423         for (ic = iphash_table[i]; ic; ic = ic->next) {
424             if (ic->sar->host_port == 0) {
425                 ap_snprintf(buf, sizeof(buf), "%pA:*", &ic->sar->host_addr);
426             }
427             else {
428                 ap_snprintf(buf, sizeof(buf), "%pA:%u", &ic->sar->host_addr,
429                     ic->sar->host_port);
430             }
431             if (ic->names == NULL) {
432                 ap_fprintf(f, "%-22s %s (%s:%u)\n", buf,
433                     ic->server->server_hostname, ic->server->defn_name,
434                     ic->server->defn_line_number);
435                 continue;
436             }
437             ap_fprintf(f, "%-22s is a NameVirtualHost\n"
438                        "%22s default server %s (%s:%u)\n",
439                        buf, "", ic->server->server_hostname,
440                        ic->server->defn_name, ic->server->defn_line_number);
441             for (nc = ic->names; nc; nc = nc->next) {
442                 if (nc->sar->host_port) {
443                     ap_fprintf(f, "%22s port %u ", "", nc->sar->host_port);
444                 }
445                 else {
446                     ap_fprintf(f, "%22s port * ", "");
447                 }
448                 ap_fprintf(f, "namevhost %s (%s:%u)\n",
449                         nc->server->server_hostname,
450                         nc->server->defn_name,
451                         nc->server->defn_line_number);
452             }
453         }
454     }
455     if (default_list) {
456         ap_fprintf(f, "_default_ servers:\n");
457         for (ic = default_list; ic; ic = ic->next) {
458             if (ic->sar->host_port == 0) {
459                 ap_fprintf(f, "port * ");
460             }
461             else {
462                 ap_fprintf(f, "port %u ", ic->sar->host_port);
463             }
464             ap_fprintf(f, "server %s (%s:%u)\n",
465                 ic->server->server_hostname, ic->server->defn_name,
466                 ic->server->defn_line_number);
467         }
468     }
469 }
470
471 /* compile the tables and such we need to do the run-time vhost lookups */
472 void ap_fini_vhost_config(ap_context_t *p, server_rec *main_s)
473 {
474     server_addr_rec *sar;
475     int has_default_vhost_addr;
476     server_rec *s;
477     int i;
478     ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
479
480     /* terminate the name_vhost list */
481     *name_vhost_list_tail = NULL;
482
483     /* Main host first */
484     s = main_s;
485
486     if (!s->server_hostname) {
487         s->server_hostname = ap_get_local_host(p);
488     }
489
490     /* initialize the tails */
491     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
492         iphash_table_tail[i] = &iphash_table[i];
493     }
494
495     /* The first things to go into the hash ap_table_t are the NameVirtualHosts
496      * Since name_vhost_list is in the same order that the directives
497      * occured in the config file, we'll copy it in that order.
498      */
499     for (sar = name_vhost_list; sar; sar = sar->next) {
500         unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
501         ipaddr_chain *new = new_ipaddr_chain(p, NULL, sar);
502
503         *iphash_table_tail[bucket] = new;
504         iphash_table_tail[bucket] = &new->next;
505
506         /* Notice that what we've done is insert an ipaddr_chain with
507          * both server and names NULL.  Remember that.
508          */
509     }
510
511     /* The next things to go into the hash ap_table_t are the virtual hosts
512      * themselves.  They're listed off of main_s->next in the reverse
513      * order they occured in the config file, so we insert them at
514      * the iphash_table_tail but don't advance the tail.
515      */
516
517     for (s = main_s->next; s; s = s->next) {
518         has_default_vhost_addr = 0;
519         for (sar = s->addrs; sar; sar = sar->next) {
520             ipaddr_chain *ic;
521
522             if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
523                 || sar->host_addr.s_addr == INADDR_ANY) {
524                 /* add it to default bucket for each appropriate sar
525                  * since we need to do a port test
526                  */
527                 ipaddr_chain *other;
528
529                 other = find_default_server(sar->host_port);
530                 if (other && other->sar->host_port != 0) {
531                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
532                             "_default_ VirtualHost overlap on port %u,"
533                             " the first has precedence", sar->host_port);
534                 }
535                 has_default_vhost_addr = 1;
536                 ic = new_ipaddr_chain(p, s, sar);
537                 ic->next = default_list;
538                 default_list = ic;
539             }
540             else {
541                 /* see if it matches something we've already got */
542                 ic = find_ipaddr(&sar->host_addr, sar->host_port);
543
544                 /* the first time we encounter a NameVirtualHost address
545                  * ic->server will be NULL, on subsequent encounters
546                  * ic->names will be non-NULL.
547                  */
548                 if (ic && (ic->names || ic->server == NULL)) {
549                     name_chain *nc = new_name_chain(p, s, sar);
550                     nc->next = ic->names;
551                     ic->names = nc;
552                     ic->server = s;
553                     if (sar->host_port != ic->sar->host_port) {
554                         /* one of the two is a * port, the other isn't */
555                         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
556                                 "VirtualHost %s:%u -- mixing * "
557                                 "ports and non-* ports with "
558                                 "a NameVirtualHost address is not supported,"
559                                 " proceeding with undefined results",
560                                 sar->virthost, sar->host_port);
561                     }
562                 }
563                 else if (ic) {
564                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
565                             "VirtualHost %s:%u overlaps with "
566                             "VirtualHost %s:%u, the first has precedence, "
567                             "perhaps you need a NameVirtualHost directive",
568                             sar->virthost, sar->host_port,
569                             ic->sar->virthost, ic->sar->host_port);
570                     ic->sar = sar;
571                     ic->server = s;
572                 }
573                 else {
574                     unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
575
576                     ic = new_ipaddr_chain(p, s, sar);
577                     ic->next = *iphash_table_tail[bucket];
578                     *iphash_table_tail[bucket] = ic;
579                 }
580             }
581         }
582
583         /* Ok now we want to set up a server_hostname if the user was
584          * silly enough to forget one.
585          * XXX: This is silly we should just crash and burn.
586          */
587         if (!s->server_hostname) {
588             if (has_default_vhost_addr) {
589                 s->server_hostname = main_s->server_hostname;
590             }
591             else if (!s->addrs) {
592                 /* what else can we do?  at this point this vhost has
593                     no configured name, probably because they used
594                     DNS in the VirtualHost statement.  It's disabled
595                     anyhow by the host matching code.  -djg */
596                 s->server_hostname =
597                     ap_pstrdup(p, "bogus_host_without_forward_dns");
598             }
599             else {
600                 struct hostent *h;
601
602                 if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
603                                         sizeof(struct in_addr), AF_INET))) {
604                     s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
605                 }
606                 else {
607                     /* again, what can we do?  They didn't specify a
608                        ServerName, and their DNS isn't working. -djg */
609                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
610                             "Failed to resolve server name "
611                             "for %s (check DNS) -- or specify an explicit "
612                             "ServerName",
613                             inet_ntoa(s->addrs->host_addr));
614                     s->server_hostname =
615                         ap_pstrdup(p, "bogus_host_without_reverse_dns");
616                 }
617             }
618         }
619     }
620
621     /* now go through and delete any NameVirtualHosts that didn't have any
622      * hosts associated with them.  Lamers.
623      */
624     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
625         ipaddr_chain **pic = &iphash_table[i];
626
627         while (*pic) {
628             ipaddr_chain *ic = *pic;
629
630             if (ic->server == NULL) {
631                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
632                         "NameVirtualHost %s:%u has no VirtualHosts",
633                         ic->sar->virthost, ic->sar->host_port);
634                 *pic = ic->next;
635             }
636             else if (ic->names == NULL) {
637                 /* if server != NULL and names == NULL then we're done
638                  * looking at NameVirtualHosts
639                  */
640                 break;
641             }
642             else {
643                 pic = &ic->next;
644             }
645         }
646     }
647
648 #ifdef IPHASH_STATISTICS
649     dump_iphash_statistics(main_s);
650 #endif
651     if (getenv("DUMP_VHOSTS")) {
652         ap_file_t *thefile = NULL;
653         ap_open_stderr(&thefile, p);
654         dump_vhost_config(thefile);
655     }
656 }
657
658
659 /*****************************************************************************
660  * run-time vhost matching functions
661  */
662
663 /* Lowercase and remove any trailing dot and/or :port from the hostname,
664  * and check that it is sane.
665  */
666 static void fix_hostname(request_rec *r)
667 {
668     char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
669     const char *src;
670     char *dst;
671
672     /* check and copy the host part */
673     src = r->hostname;
674     dst = host;
675     while (*src) {
676         if (!ap_isalnum(*src) && *src != '.' && *src != '-') {
677             if (*src == ':')
678                 break;
679             else
680                 goto bad;
681         } else {
682             *dst++ = *src++;
683         }
684     }
685     /* check the port part */
686     if (*src++ == ':') {
687         while (*src) {
688             if (!ap_isdigit(*src++)) {
689                 goto bad;
690             }
691         }
692     }
693     /* strip trailing gubbins */
694     if (dst > host && dst[-1] == '.') {
695         dst[-1] = '\0';
696     } else {
697         dst[0] = '\0';
698     }
699
700     r->hostname = host;
701     return;
702
703 bad:
704     r->status = HTTP_BAD_REQUEST;
705     ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
706                   "Client sent malformed Host header");
707     return;
708 }
709
710
711 /* return 1 if host matches ServerName or ServerAliases */
712 static int matches_aliases(server_rec *s, const char *host)
713 {
714     int i;
715     ap_array_header_t *names;
716
717     /* match ServerName */
718     if (!strcasecmp(host, s->server_hostname)) {
719         return 1;
720     }
721
722     /* search all the aliases from ServerAlias directive */
723     names = s->names;
724     if (names) {
725         char **name = (char **) names->elts;
726         for (i = 0; i < names->nelts; ++i) {
727             if(!name[i]) continue;
728             if (!strcasecmp(host, name[i]))
729                 return 1;
730         }
731     }
732     names = s->wild_names;
733     if (names) {
734         char **name = (char **) names->elts;
735         for (i = 0; i < names->nelts; ++i) {
736             if(!name[i]) continue;
737             if (!ap_strcasecmp_match(host, name[i]))
738                 return 1;
739         }
740     }
741     return 0;
742 }
743
744
745 /* Suppose a request came in on the same socket as this r, and included
746  * a header "Host: host:port", would it map to r->server?  It's more
747  * than just that though.  When we do the normal matches for each request
748  * we don't even bother considering Host: etc on non-namevirtualhosts,
749  * we just call it a match.  But here we require the host:port to match
750  * the ServerName and/or ServerAliases.
751  */
752 API_EXPORT(int) ap_matches_request_vhost(request_rec *r, const char *host,
753     unsigned port)
754 {
755     server_rec *s;
756     server_addr_rec *sar;
757
758     s = r->server;
759
760     /* search all the <VirtualHost> values */
761     /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
762      * consider: 
763      *
764      *     NameVirtualHost 10.1.1.1
765      *     <VirtualHost 10.1.1.1>
766      *     ServerName v1
767      *     </VirtualHost>
768      *     <VirtualHost 10.1.1.1>
769      *     ServerName v2
770      *     </VirtualHost>
771      *
772      * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll say
773      * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
774      * it would really go to v1.
775      */
776     for (sar = s->addrs; sar; sar = sar->next) {
777         if ((sar->host_port == 0 || port == sar->host_port)
778             && !strcasecmp(host, sar->virthost)) {
779             return 1;
780         }
781     }
782
783     /* the Port has to match now, because the rest don't have ports associated
784      * with them. */
785     if (port != s->port) {
786         return 0;
787     }
788
789     return matches_aliases(s, host);
790 }
791
792
793 static void check_hostalias(request_rec *r)
794 {
795     /*
796      * Even if the request has a Host: header containing a port we ignore
797      * that port.  We always use the physical port of the socket.  There
798      * are a few reasons for this:
799      *
800      * - the default of 80 or 443 for SSL is easier to handle this way
801      * - there is less of a possibility of a security problem
802      * - it simplifies the data structure
803      * - the client may have no idea that a proxy somewhere along the way
804      *   translated the request to another ip:port
805      * - except for the addresses from the VirtualHost line, none of the other
806      *   names we'll match have ports associated with them
807      */
808     const char *host = r->hostname;
809     unsigned port = ntohs(r->connection->local_addr.sin_port);
810     server_rec *s;
811     server_rec *last_s;
812     name_chain *src;
813
814     last_s = NULL;
815
816     /* Recall that the name_chain is a list of server_addr_recs, some of
817      * whose ports may not match.  Also each server may appear more than
818      * once in the chain -- specifically, it will appear once for each
819      * address from its VirtualHost line which matched.  We only want to
820      * do the full ServerName/ServerAlias comparisons once for each
821      * server, fortunately we know that all the VirtualHost addresses for
822      * a single server are adjacent to each other.
823      */
824
825     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
826         server_addr_rec *sar;
827
828         /* We only consider addresses on the name_chain which have a matching
829          * port
830          */
831         sar = src->sar;
832         if (sar->host_port != 0 && port != sar->host_port) {
833             continue;
834         }
835
836         s = src->server;
837
838         /* does it match the virthost from the sar? */
839         if (!strcasecmp(host, sar->virthost)) {
840             goto found;
841         }
842
843         if (s == last_s) {
844             /* we've already done ServerName and ServerAlias checks for this
845              * vhost
846              */
847             continue;
848         }
849         last_s = s;
850
851         if (matches_aliases(s, host)) {
852             goto found;
853         }
854     }
855     return;
856
857 found:
858     /* s is the first matching server, we're done */
859     r->server = s;
860 }
861
862
863 static void check_serverpath(request_rec *r)
864 {
865     server_rec *s;
866     server_rec *last_s;
867     name_chain *src;
868     /* use AP func here. */
869     unsigned port = ntohs(r->connection->local_addr.sin_port);
870
871     /*
872      * This is in conjunction with the ServerPath code in http_core, so we
873      * get the right host attached to a non- Host-sending request.
874      *
875      * See the comment in check_hostalias about how each vhost can be
876      * listed multiple times.
877      */
878
879     last_s = NULL;
880     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
881         /* We only consider addresses on the name_chain which have a matching
882          * port
883          */
884         if (src->sar->host_port != 0 && port != src->sar->host_port) {
885             continue;
886         }
887
888         s = src->server;
889         if (s == last_s) {
890             continue;
891         }
892         last_s = s;
893
894         if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
895             (s->path[s->pathlen - 1] == '/' ||
896              r->uri[s->pathlen] == '/' ||
897              r->uri[s->pathlen] == '\0')) {
898             r->server = s;
899             return;
900         }
901     }
902 }
903
904
905 void ap_update_vhost_from_headers(request_rec *r)
906 {
907     /* must set this for HTTP/1.1 support */
908     if (r->hostname || (r->hostname = ap_table_get(r->headers_in, "Host"))) {
909         fix_hostname(r);
910         if (r->status != HTTP_OK)
911             return;
912     }
913     /* check if we tucked away a name_chain */
914     if (r->connection->vhost_lookup_data) {
915         if (r->hostname)
916             check_hostalias(r);
917         else
918             check_serverpath(r);
919     }
920 }
921
922
923 /* Called for a new connection which has a known local_addr.  Note that the
924  * new connection is assumed to have conn->server == main server.
925  */
926 void ap_update_vhost_given_ip(conn_rec *conn)
927 {
928     ipaddr_chain *trav;
929     unsigned port = ntohs(conn->local_addr.sin_port);
930
931     /* scan the hash ap_table_t for an exact match first */
932     trav = find_ipaddr(&conn->local_addr.sin_addr, port);
933     if (trav) {
934         /* save the name_chain for later in case this is a name-vhost */
935         conn->vhost_lookup_data = trav->names;
936         conn->base_server = trav->server;
937         return;
938     }
939
940     /* There's certainly no name-vhosts with this address, they would have
941      * been matched above.
942      */
943     conn->vhost_lookup_data = NULL;
944
945     /* maybe there's a default server matching this port */
946     trav = find_default_server(port);
947     if (trav) {
948         conn->base_server = trav->server;
949     }
950
951     /* otherwise we're stuck with just the main server */
952 }