Apache HTTPD
vhost.c
Go to the documentation of this file.
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
23#include "apr.h"
24#include "apr_strings.h"
25#include "apr_lib.h"
26#include "apr_version.h"
27
28#define APR_WANT_STRFUNC
29#include "apr_want.h"
30
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#include "http_main.h"
39
40#if APR_HAVE_ARPA_INET_H
41#include <arpa/inet.h>
42#endif
43
44/* we know core's module_index is 0 */
45#undef APLOG_MODULE_INDEX
46#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
47
48/*
49 * After all the definitions there's an explanation of how it's all put
50 * together.
51 */
52
53/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
54 * lists of name-vhosts.
55 */
56typedef struct name_chain name_chain;
57struct name_chain {
59 server_addr_rec *sar; /* the record causing it to be in
60 * this chain (needed for port comparisons) */
61 server_rec *server; /* the server to use on a match */
62};
63
64/* meta-list of ip addresses. Each server_rec can be in possibly multiple
65 * hash chains since it can have multiple ips.
66 */
70 server_addr_rec *sar; /* the record causing it to be in
71 * this chain (need for both ip addr and port
72 * comparisons) */
73 server_rec *server; /* the server to use if this matches */
74 name_chain *names; /* if non-NULL then a list of name-vhosts
75 * sharing this address */
76 name_chain *initialnames; /* no runtime use, temporary storage of first
77 * NVH'es names */
78};
79
80/* This defines the size of the hash table used for hashing ip addresses
81 * of virtual hosts. It must be a power of two.
82 */
83#ifndef IPHASH_TABLE_SIZE
84#define IPHASH_TABLE_SIZE 256
85#endif
86
87/* A (n) bucket hash table, each entry has a pointer to a server rec and
88 * a pointer to the other entries in that bucket. Each individual address,
89 * even for virtualhosts with multiple addresses, has an entry in this hash
90 * table. There are extra buckets for _default_, and name-vhost entries.
91 *
92 * Note that after config time this is constant, so it is thread-safe.
93 */
95
96/* dump out statistics about the hash function */
97/* #define IPHASH_STATISTICS */
98
99/* list of the _default_ servers */
101
102/* whether a config error was seen */
103static int config_error = 0;
104
105/* config check function */
107 apr_pool_t *ptemp, server_rec *s);
108
109/*
110 * How it's used:
111 *
112 * The ip address determines which chain in iphash_table is interesting, then
113 * a comparison is done down that chain to find the first ipaddr_chain whose
114 * sar matches the address:port pair.
115 *
116 * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
117 *
118 * Otherwise it's a name-vhost list, and the default is the server in the
119 * ipaddr_chain record. We tuck away the ipaddr_chain record in the
120 * conn_rec field vhost_lookup_data. Later on after the headers we get a
121 * second chance, and we use the name_chain to figure out what name-vhost
122 * matches the headers.
123 *
124 * If there was no ip address match in the iphash_table then do a lookup
125 * in the default_list.
126 *
127 * How it's put together ... well you should be able to figure that out
128 * from how it's used. Or something like that.
129 */
130
131
132/* called at the beginning of the config */
139
140
141/*
142 * Parses a host of the form <address>[:port]
143 * paddr is used to create a list in the order of input
144 * **paddr is the ->next pointer of the last entry (or s->addrs)
145 * *paddr is the variable used to keep track of **paddr between calls
146 * port is the default port to assume
147 */
148static const char *get_addresses(apr_pool_t *p, const char *w_,
150 apr_port_t default_port)
151{
153 server_addr_rec *sar;
154 char *w, *host, *scope_id;
155 int wild_port;
158 apr_status_t rv;
159
160 if (*w_ == '\0')
161 return NULL;
162
163 wlen = strlen(w_); /* wlen must be > 0 at this point */
164 w = apr_pstrmemdup(p, w_, wlen);
165 /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
166 wild_port = 0;
167 if (w[wlen - 1] == '*') {
168 if (wlen < 2) {
169 wild_port = 1;
170 }
171 else if (w[wlen - 2] == ':') {
172 w[wlen - 2] = '\0';
173 wild_port = 1;
174 }
175 }
176 rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
177 /* If the string is "80", apr_parse_addr_port() will be happy and set
178 * host to NULL and port to 80, so watch out for that.
179 */
180 if (rv != APR_SUCCESS) {
181 return "The address or port is invalid";
182 }
183 if (!host) {
184 return "Missing address for VirtualHost";
185 }
186#if !APR_VERSION_AT_LEAST(1,7,0)
187 if (scope_id) {
188 return apr_pstrcat(p,
189 "Scope ID in address '", w,
190 "' not supported with APR " APR_VERSION_STRING,
191 NULL);
192 }
193#endif
194 if (!port && !wild_port) {
195 port = default_port;
196 }
197
198 if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
200 if (rv) {
201 return "Could not determine a wildcard address ('0.0.0.0') -- "
202 "check resolver configuration.";
203 }
204 }
205 else {
207 if (rv != APR_SUCCESS) {
209 "Could not resolve host name %s -- ignoring!", host);
210 return NULL;
211 }
212#if APR_VERSION_AT_LEAST(1,7,0)
213 if (scope_id) {
215 if (rv) {
217 "Could not set scope ID %s for %pI -- ignoring!",
219 return NULL;
220 }
221 }
222#endif
223 }
224
225 /* Remember all addresses for the host */
226
227 do {
228 sar = apr_pcalloc(p, sizeof(server_addr_rec));
229 **paddr = sar;
230 *paddr = &sar->next;
231 sar->host_addr = my_addr;
232 sar->host_port = port;
233 sar->virthost = host;
234 my_addr = my_addr->next;
235 } while (my_addr);
236
237 return NULL;
238}
239
240
241/* parse the <VirtualHost> addresses */
243 const char *hostname,
244 server_rec *s)
245{
246 server_addr_rec **addrs;
247 const char *err;
248
249 /* start the list of addresses */
250 addrs = &s->addrs;
251 while (hostname[0]) {
252 err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
253 if (err) {
254 *addrs = NULL;
255 return err;
256 }
257 }
258 /* terminate the list */
259 *addrs = NULL;
260 if (s->addrs) {
261 if (s->addrs->host_port) {
262 /* override the default port which is inherited from main_server */
263 s->port = s->addrs->host_port;
264 }
265 }
266 return NULL;
267}
268
269
271 void *dummy,
272 const char *arg)
273{
274 static int warnonce = 0;
275 if (++warnonce == 1) {
277 "NameVirtualHost has no effect and will be removed in the "
278 "next release %s:%d",
279 cmd->directive->filename,
280 cmd->directive->line_num);
281 }
282
283 return NULL;
284}
285
286
287/* hash table statistics, keep this in here for the beta period so
288 * we can find out if the hash function is ok
289 */
290#ifdef IPHASH_STATISTICS
291static int iphash_compare(const void *a, const void *b)
292{
293 return (*(const int *) b - *(const int *) a);
294}
295
296
298{
299 unsigned count[IPHASH_TABLE_SIZE];
300 int i;
302 unsigned total;
303 char buf[HUGE_STRING_LEN];
304 char *p;
305
306 total = 0;
307 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
308 count[i] = 0;
309 for (src = iphash_table[i]; src; src = src->next) {
310 ++count[i];
311 if (i < IPHASH_TABLE_SIZE) {
312 /* don't count the slop buckets in the total */
313 ++total;
314 }
315 }
316 }
318 p = buf + apr_snprintf(buf, sizeof(buf),
319 APLOGNO(03235) "iphash: total hashed = %u, avg chain = %u, "
320 "chain lengths (count x len):",
321 total, total / IPHASH_TABLE_SIZE);
322 total = 1;
323 for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
324 if (count[i - 1] != count[i]) {
325 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
326 total, count[i - 1]);
327 total = 1;
328 }
329 else {
330 ++total;
331 }
332 }
333 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
334 total, count[IPHASH_TABLE_SIZE - 1]);
335 /* Intentional no APLOGNO */
336 /* buf provides APLOGNO */
338}
339#endif
340
341
342/* This hashing function is designed to get good distribution in the cases
343 * where the server is handling entire "networks" of servers. i.e. a
344 * whack of /24s. This is probably the most common configuration for
345 * ISPs with large virtual servers.
346 *
347 * NOTE: This function is symmetric (i.e. collapses all 4 octets
348 * into one), so machine byte order (big/little endianness) does not matter.
349 *
350 * Hash function provided by David Hankins.
351 */
352static APR_INLINE unsigned hash_inaddr(unsigned key)
353{
354 key ^= (key >> 16);
355 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
356}
357
358static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
359{
360 unsigned key;
361
362 /* The key is the last four bytes of the IP address.
363 * For IPv4, this is the entire address, as always.
364 * For IPv6, this is usually part of the MAC address.
365 */
366 key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
367 return hash_inaddr(key);
368}
369
372{
373 ipaddr_chain *new;
374
375 new = apr_palloc(p, sizeof(*new));
376 new->names = NULL;
377 new->initialnames = NULL;
378 new->server = s;
379 new->sar = sar;
380 new->next = NULL;
381 return new;
382}
383
384
387{
388 name_chain *new;
389
390 new = apr_palloc(p, sizeof(*new));
391 new->server = s;
392 new->sar = sar;
393 new->next = NULL;
394 return new;
395}
396
397
399{
400 unsigned bucket;
403
404 /* scan the hash table for an exact match first */
405 bucket = hash_addr(sa);
406 for (trav = iphash_table[bucket]; trav; trav = trav->next) {
407 server_addr_rec *sar = trav->sar;
409
410 if (cur->port == sa->port) {
411 if (apr_sockaddr_equal(cur, sa)) {
412 return trav;
413 }
414 }
415 if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
416 if (apr_sockaddr_equal(cur, sa)) {
417 /* don't break, continue looking for an exact match */
419 }
420 }
421 }
422 return wild_match;
423}
424
426{
427 server_addr_rec *sar;
430
431 for (trav = default_list; trav; trav = trav->next) {
432 sar = trav->sar;
433 if (sar->host_port == port) {
434 /* match! */
435 return trav;
436 }
437 if (wild_match == NULL && sar->host_port == 0) {
438 /* don't break, continue looking for an exact match */
440 }
441 }
442 return wild_match;
443}
444
445#if APR_HAVE_IPV6
446#define IS_IN6_ANYADDR(ad) ((ad)->family == APR_INET6 \
447 && IN6_IS_ADDR_UNSPECIFIED(&(ad)->sa.sin6.sin6_addr))
448#else
449#define IS_IN6_ANYADDR(ad) (0)
450#endif
451
453{
454 name_chain *nc;
455 int len;
456 char buf[MAX_STRING_LEN];
457 apr_sockaddr_t *ha = ic->sar->host_addr;
458
459 if ((ha->family == APR_INET && ha->sa.sin.sin_addr.s_addr == INADDR_ANY)
460 || IS_IN6_ANYADDR(ha)) {
461 len = apr_snprintf(buf, sizeof(buf), "*:%u",
462 ic->sar->host_port);
463 }
464 else {
465 len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
466 }
467 if (ic->sar->host_port == 0) {
468 buf[len-1] = '*';
469 }
470 if (ic->names == NULL) {
471 apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
472 ic->server->server_hostname,
473 ic->server->defn_name, ic->server->defn_line_number);
474 return;
475 }
476 apr_file_printf(f, "%-22s is a NameVirtualHost\n"
477 "%8s default server %s (%s:%u)\n",
478 buf, "", ic->server->server_hostname,
479 ic->server->defn_name, ic->server->defn_line_number);
480 for (nc = ic->names; nc; nc = nc->next) {
481 if (nc->sar->host_port) {
482 apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
483 }
484 else {
485 apr_file_printf(f, "%8s port * ", "");
486 }
487 apr_file_printf(f, "namevhost %s (%s:%u)\n",
488 nc->server->server_hostname,
489 nc->server->defn_name, nc->server->defn_line_number);
490 if (nc->server->names) {
491 apr_array_header_t *names = nc->server->names;
492 char **name = (char **)names->elts;
493 int i;
494 for (i = 0; i < names->nelts; ++i) {
495 if (name[i]) {
496 apr_file_printf(f, "%16s alias %s\n", "", name[i]);
497 }
498 }
499 }
500 if (nc->server->wild_names) {
501 apr_array_header_t *names = nc->server->wild_names;
502 char **name = (char **)names->elts;
503 int i;
504 for (i = 0; i < names->nelts; ++i) {
505 if (name[i]) {
506 apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
507 }
508 }
509 }
510 }
511}
512
514{
516 int i;
517
518 apr_file_printf(f, "VirtualHost configuration:\n");
519
520 /* non-wildcard servers */
521 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
522 for (ic = iphash_table[i]; ic; ic = ic->next) {
523 dump_a_vhost(f, ic);
524 }
525 }
526
527 /* wildcard servers */
528 for (ic = default_list; ic; ic = ic->next) {
529 dump_a_vhost(f, ic);
530 }
531}
532
533
534/*
535 * When a second or later virtual host maps to the same IP chain,
536 * add the relevant server names to the chain. Special care is taken
537 * to avoid adding ic->names until we're sure there are multiple VH'es.
538 */
542{
543
544 name_chain *nc = new_name_chain(p, s, sar);
545 nc->next = ic->names;
546
547 /* iterating backwards, so each one we see becomes the current default server */
548 ic->server = s;
549
550 if (ic->names == NULL) {
551 if (ic->initialnames == NULL) {
552 /* first pass, set these names aside in case we see another VH.
553 * Until then, this looks like an IP-based VH to runtime.
554 */
555 ic->initialnames = nc;
556 }
557 else {
558 /* second pass through this chain -- this really is an NVH, and we
559 * have two sets of names to link in.
560 */
561 nc->next = ic->initialnames;
562 ic->names = nc;
563 ic->initialnames = NULL;
564 }
565 }
566 else {
567 /* 3rd or more -- just keep stacking the names */
568 ic->names = nc;
569 }
570}
571
572/* compile the tables and such we need to do the run-time vhost lookups */
574{
575 server_addr_rec *sar;
577 server_rec *s;
578 int i;
580
581 /* Main host first */
582 s = main_s;
583
584 if (!s->server_hostname) {
585 s->server_hostname = ap_get_local_host(p);
586 }
587
588 /* initialize the tails */
589 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
591 }
592
593 /* The next things to go into the hash table are the virtual hosts
594 * themselves. They're listed off of main_s->next in the reverse
595 * order they occurred in the config file, so we insert them at
596 * the iphash_table_tail but don't advance the tail.
597 */
598
599 for (s = main_s->next; s; s = s->next) {
602 for (sar = s->addrs; sar; sar = sar->next) {
604 char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
605 /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */
608
609 if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server" */
610 if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len)
611 || sar_prev->host_port != sar->host_port) {
613 }
614 }
615 else {
616 /* No default server, or we found a default server but
617 ** exactly one of us is a wildcard port, which means we want
618 ** two ip-based vhosts not an NVH with two names
619 */
620 ic = new_ipaddr_chain(p, s, sar);
621 ic->next = default_list;
624 }
626 }
627 else {
628 /* see if it matches something we've already got */
629 ic = find_ipaddr(sar->host_addr);
630
631 if (!ic || sar->host_port != ic->sar->host_port) {
632 /* No matching server, or we found a matching server but
633 ** exactly one of us is a wildcard port, which means we want
634 ** two ip-based vhosts not an NVH with two names
635 */
636 unsigned bucket = hash_addr(sar->host_addr);
637 ic = new_ipaddr_chain(p, s, sar);
638 ic->next = *iphash_table_tail[bucket];
639 *iphash_table_tail[bucket] = ic;
640 }
642 }
643 sar_prev = sar;
644 }
645
646 /* Ok now we want to set up a server_hostname if the user was
647 * silly enough to forget one.
648 * XXX: This is silly we should just crash and burn.
649 */
650 if (!s->server_hostname) {
652 s->server_hostname = main_s->server_hostname;
653 }
654 else if (!s->addrs) {
655 /* what else can we do? at this point this vhost has
656 no configured name, probably because they used
657 DNS in the VirtualHost statement. It's disabled
658 anyhow by the host matching code. -djg */
659 s->server_hostname =
660 apr_pstrdup(p, "bogus_host_without_forward_dns");
661 }
662 else {
663 apr_status_t rv;
664 char *hostname;
665
666 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
667 if (rv == APR_SUCCESS) {
668 s->server_hostname = apr_pstrdup(p, hostname);
669 }
670 else {
671 /* again, what can we do? They didn't specify a
672 ServerName, and their DNS isn't working. -djg */
673 char *ipaddr_str;
674
675 apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
677 "Failed to resolve server name "
678 "for %s (check DNS) -- or specify an explicit "
679 "ServerName",
680 ipaddr_str);
681 s->server_hostname =
682 apr_pstrdup(p, "bogus_host_without_reverse_dns");
683 }
684 }
685 }
686 }
687
688#ifdef IPHASH_STATISTICS
690#endif
691 if (ap_exists_config_define("DUMP_VHOSTS")) {
695 }
696}
697
699 apr_pool_t *ptemp, server_rec *s)
700{
701 return config_error ? !OK : OK;
702}
703
704/*****************************************************************************
705 * run-time vhost matching functions
706 */
707
709{
710 char *dst;
711 int double_colon = 0;
712
713 for (dst = host; *dst; dst++) {
714 if (apr_isxdigit(*dst)) {
715 if (apr_isupper(*dst)) {
716 *dst = apr_tolower(*dst);
717 }
718 }
719 else if (*dst == ':') {
720 if (*(dst + 1) == ':') {
721 if (double_colon)
722 return APR_EINVAL;
723 double_colon = 1;
724 }
725 else if (*(dst + 1) == '.') {
726 return APR_EINVAL;
727 }
728 }
729 else if (*dst == '.') {
730 /* For IPv4-mapped IPv6 addresses like ::FFFF:129.144.52.38 */
731 if (*(dst + 1) == ':' || *(dst + 1) == '.')
732 return APR_EINVAL;
733 }
734 else {
735 return APR_EINVAL;
736 }
737 }
738 return APR_SUCCESS;
739}
740
742{
743 char *dst;
744
745 for (dst = host; *dst; dst++) {
746 if (apr_islower(*dst)) {
747 /* leave char unchanged */
748 }
749 else if (*dst == '.') {
750 if (*(dst + 1) == '.') {
751 return APR_EINVAL;
752 }
753 }
754 else if (apr_isupper(*dst)) {
755 *dst = apr_tolower(*dst);
756 }
757 else if (*dst == '/' || *dst == '\\') {
758 return APR_EINVAL;
759 }
760 }
761 /* strip trailing gubbins */
762 if (dst > host && dst[-1] == '.') {
763 dst[-1] = '\0';
764 }
765 return APR_SUCCESS;
766}
767
768/*
769 * If strict mode ever becomes the default, this should be folded into
770 * fix_hostname_non_v6()
771 */
773{
774 char *ch;
775 int is_dotted_decimal = 1, leading_zeroes = 0, dots = 0;
776
777 for (ch = host; *ch; ch++) {
778 if (apr_isalpha(*ch) || *ch == '-' || *ch == '_') {
780 }
781 else if (ch[0] == '.') {
782 dots++;
783 if (ch[1] == '0' && apr_isdigit(ch[2]))
784 leading_zeroes = 1;
785 }
786 else if (!apr_isdigit(*ch)) {
787 /* also takes care of multiple Host headers by denying commas */
788 goto bad;
789 }
790 }
791 if (is_dotted_decimal) {
792 if (host[0] == '.' || (host[0] == '0' && apr_isdigit(host[1])))
793 leading_zeroes = 1;
794 if (leading_zeroes || dots != 3) {
795 /* RFC 3986 7.4 */
796 goto bad;
797 }
798 }
799 else {
800 /* The top-level domain must start with a letter (RFC 1123 2.1) */
801 while (ch > host && *ch != '.')
802 ch--;
803 if (ch[0] == '.' && ch[1] != '\0' && !apr_isalpha(ch[1]))
804 goto bad;
805 }
806 return APR_SUCCESS;
807
808bad:
810 "[strict] Invalid host name '%s'%s%.6s",
811 host, *ch ? ", problem near: " : "", ch);
812 return APR_EINVAL;
813}
814
815/* Lowercase and remove any trailing dot and/or :port from the hostname,
816 * and check that it is sane.
817 *
818 * In most configurations the exact syntax of the hostname isn't
819 * important so strict sanity checking isn't necessary. However, in
820 * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
821 * the hostname is interpolated into the filename, we need to be sure
822 * that the interpolation doesn't expose parts of the filesystem.
823 * We don't do strict RFC 952 / RFC 1123 syntax checking in order
824 * to support iDNS and people who erroneously use underscores.
825 * Instead we just check for filesystem metacharacters: directory
826 * separators / and \ and sequences of more than one dot.
827 */
828static int fix_hostname(request_rec *r, const char *host_header,
829 unsigned http_conformance)
830{
831 const char *src;
832 char *host, *scope_id;
834 apr_status_t rv;
835 const char *c;
836 int is_v6literal = 0;
837 int strict = (http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
838
840
841 /* According to RFC 2616, Host header field CAN be blank */
842 if (!*src) {
843 return is_v6literal;
844 }
845
846 /* apr_parse_addr_port will interpret a bare integer as a port
847 * which is incorrect in this context. So treat it separately.
848 */
849 for (c = src; apr_isdigit(*c); ++c);
850 if (!*c) {
851 /* pure integer */
852 if (strict) {
853 /* RFC 3986 7.4 */
855 "[strict] purely numeric host names not allowed: %s",
856 src);
857 goto bad_nolog;
858 }
859 r->hostname = src;
860 return is_v6literal;
861 }
862
863 if (host_header) {
865 if (rv != APR_SUCCESS || scope_id)
866 goto bad;
867 if (port) {
868 /* Don't throw the Host: header's port number away:
869 save it in parsed_uri -- ap_get_server_port() needs it! */
870 /* @@@ XXX there should be a better way to pass the port.
871 * Like r->hostname, there should be a r->portno
872 */
875 }
876 if (host_header[0] == '[')
877 is_v6literal = 1;
878 }
879 else {
880 /*
881 * Already parsed, surrounding [ ] (if IPv6 literal) and :port have
882 * already been removed.
883 */
885 if (ap_strchr(host, ':') != NULL)
886 is_v6literal = 1;
887 }
888
889 if (is_v6literal) {
891 }
892 else {
894 if (strict && rv == APR_SUCCESS)
896 }
897 if (rv != APR_SUCCESS)
898 goto bad;
899
900 r->hostname = host;
901 return is_v6literal;
902
903bad:
905 "Client sent malformed Host header: %s",
906 src);
909 return is_v6literal;
910}
911
912/* return 1 if host matches ServerName or ServerAliases */
913static int matches_aliases(server_rec *s, const char *host)
914{
915 int i;
917
918 /* match ServerName */
919 if (!strcasecmp(host, s->server_hostname)) {
920 return 1;
921 }
922
923 /* search all the aliases from ServerAlias directive */
924 names = s->names;
925 if (names) {
926 char **name = (char **) names->elts;
927 for (i = 0; i < names->nelts; ++i) {
928 if (!name[i]) continue;
929 if (!strcasecmp(host, name[i]))
930 return 1;
931 }
932 }
933 names = s->wild_names;
934 if (names) {
935 char **name = (char **) names->elts;
936 for (i = 0; i < names->nelts; ++i) {
937 if (!name[i]) continue;
939 return 1;
940 }
941 }
942 return 0;
943}
944
945
946/* Suppose a request came in on the same socket as this r, and included
947 * a header "Host: host:port", would it map to r->server? It's more
948 * than just that though. When we do the normal matches for each request
949 * we don't even bother considering Host: etc on non-namevirtualhosts,
950 * we just call it a match. But here we require the host:port to match
951 * the ServerName and/or ServerAliases.
952 */
955{
956 server_rec *s;
957 server_addr_rec *sar;
958
959 s = r->server;
960
961 /* search all the <VirtualHost> values */
962 /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
963 * consider:
964 *
965 * NameVirtualHost 10.1.1.1
966 * <VirtualHost 10.1.1.1>
967 * ServerName v1
968 * </VirtualHost>
969 * <VirtualHost 10.1.1.1>
970 * ServerName v2
971 * </VirtualHost>
972 *
973 * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
974 * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
975 * it would really go to v1.
976 */
977 for (sar = s->addrs; sar; sar = sar->next) {
978 if ((sar->host_port == 0 || port == sar->host_port)
979 && !strcasecmp(host, sar->virthost)) {
980 return 1;
981 }
982 }
983
984 /* the Port has to match now, because the rest don't have ports associated
985 * with them. */
986 if (port != s->port) {
987 return 0;
988 }
989
990 return matches_aliases(s, host);
991}
992
993
994/*
995 * Updates r->server from ServerName/ServerAlias. Per the interaction
996 * of ip and name-based vhosts, it only looks in the best match from the
997 * connection-level ip-based matching.
998 * Returns HTTP_BAD_REQUEST if there was no match.
999 */
1001{
1002 /*
1003 * Even if the request has a Host: header containing a port we ignore
1004 * that port. We always use the physical port of the socket. There
1005 * are a few reasons for this:
1006 *
1007 * - the default of 80 or 443 for SSL is easier to handle this way
1008 * - there is less of a possibility of a security problem
1009 * - it simplifies the data structure
1010 * - the client may have no idea that a proxy somewhere along the way
1011 * translated the request to another ip:port
1012 * - except for the addresses from the VirtualHost line, none of the other
1013 * names we'll match have ports associated with them
1014 */
1015 const char *host = r->hostname;
1017 server_rec *s;
1020 name_chain *src;
1021
1022 virthost_s = NULL;
1023 last_s = NULL;
1024
1026
1027 /* Recall that the name_chain is a list of server_addr_recs, some of
1028 * whose ports may not match. Also each server may appear more than
1029 * once in the chain -- specifically, it will appear once for each
1030 * address from its VirtualHost line which matched. We only want to
1031 * do the full ServerName/ServerAlias comparisons once for each
1032 * server, fortunately we know that all the VirtualHost addresses for
1033 * a single server are adjacent to each other.
1034 */
1035
1036 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
1037 server_addr_rec *sar;
1038
1039 /* We only consider addresses on the name_chain which have a matching
1040 * port
1041 */
1042 sar = src->sar;
1043 if (sar->host_port != 0 && port != sar->host_port) {
1044 continue;
1045 }
1046
1047 s = src->server;
1048
1049 /* If we still need to do ServerName and ServerAlias checks for this
1050 * server, do them now.
1051 */
1052 if (s != last_s) {
1053 /* does it match any ServerName or ServerAlias directive? */
1054 if (matches_aliases(s, host)) {
1055 goto found;
1056 }
1057 }
1058
1059 /* Fallback: does it match the virthost from the sar? */
1060 if (!strcasecmp(host, sar->virthost)) {
1061 /* only the first match is used */
1062 if (virthost_s == NULL) {
1063 virthost_s = s;
1064 }
1065 }
1066
1067 last_s = s;
1068 }
1069
1070 /* If ServerName and ServerAlias check failed, we end up here. If it
1071 * matches a VirtualHost, virthost_s is set. Use that as fallback
1072 */
1073 if (virthost_s) {
1074 s = virthost_s;
1075 goto found;
1076 }
1077
1078 if (!r->connection->vhost_lookup_data) {
1079 if (matches_aliases(r->server, host)) {
1080 s = r->server;
1081 goto found;
1082 }
1083 }
1084 return HTTP_BAD_REQUEST;
1085
1086found:
1087 /* s is the first matching server, we're done */
1088 r->server = s;
1089 return HTTP_OK;
1090}
1091
1092
1094{
1095 server_rec *s;
1097 name_chain *src;
1099
1101
1102 /*
1103 * This is in conjunction with the ServerPath code in http_core, so we
1104 * get the right host attached to a non- Host-sending request.
1105 *
1106 * See the comment in update_server_from_aliases about how each vhost can be
1107 * listed multiple times.
1108 */
1109
1110 last_s = NULL;
1111 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
1112 /* We only consider addresses on the name_chain which have a matching
1113 * port
1114 */
1115 if (src->sar->host_port != 0 && port != src->sar->host_port) {
1116 continue;
1117 }
1118
1119 s = src->server;
1120 if (s == last_s) {
1121 continue;
1122 }
1123 last_s = s;
1124
1125 if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
1126 (s->path[s->pathlen - 1] == '/' ||
1127 r->uri[s->pathlen] == '/' ||
1128 r->uri[s->pathlen] == '\0')) {
1129 r->server = s;
1130 return;
1131 }
1132 }
1133}
1134
1136 int is_v6literal)
1137{
1138 struct iovec iov[5];
1139 apr_size_t nvec = 0;
1140 /*
1141 * We cannot use ap_get_server_name/port here, because we must
1142 * ignore UseCanonicalName/Port.
1143 */
1144 if (is_v6literal) {
1145 iov[nvec].iov_base = "[";
1146 iov[nvec].iov_len = 1;
1147 nvec++;
1148 }
1149 iov[nvec].iov_base = (void *)r->hostname;
1150 iov[nvec].iov_len = strlen(r->hostname);
1151 nvec++;
1152 if (is_v6literal) {
1153 iov[nvec].iov_base = "]";
1154 iov[nvec].iov_len = 1;
1155 nvec++;
1156 }
1157 if (r->parsed_uri.port_str) {
1158 iov[nvec].iov_base = ":";
1159 iov[nvec].iov_len = 1;
1160 nvec++;
1161 iov[nvec].iov_base = r->parsed_uri.port_str;
1162 iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
1163 nvec++;
1164 }
1165 return apr_pstrcatv(r->pool, iov, nvec, NULL);
1166}
1167
1172
1174{
1176 const char *host_header = apr_table_get(r->headers_in, "Host");
1177 int is_v6literal = 0;
1178 int have_hostname_from_url = 0;
1179 int rc = HTTP_OK;
1180
1181 if (r->hostname) {
1182 /*
1183 * If there was a host part in the Request-URI, ignore the 'Host'
1184 * header.
1185 */
1188 }
1189 else if (host_header != NULL) {
1191 }
1192 if (!require_match && r->status != HTTP_OK)
1193 return HTTP_OK;
1194
1196 /*
1197 * If we have both hostname from an absoluteURI and a Host header,
1198 * we must ignore the Host header (RFC 2616 5.2).
1199 * To enforce this, we reset the Host header to the value from the
1200 * request line.
1201 */
1203 const char *repl = construct_host_header(r, is_v6literal);
1204 apr_table_setn(r->headers_in, "Host", repl);
1206 "Replacing host header '%s' with host '%s' given "
1207 "in the request uri", host_header, repl);
1208 }
1209 }
1210
1211 /* check if we tucked away a name_chain */
1213 if (r->hostname)
1215 else
1217 }
1218 else if (require_match && r->hostname) {
1219 /* check the base server config */
1221 }
1222
1223 return rc;
1224}
1225
1231 void* baton)
1232{
1233 server_rec *s;
1235 name_chain *src;
1237 int rv = 0;
1238
1239 if (conn->vhost_lookup_data) {
1240 last_s = NULL;
1241 port = conn->local_addr->port;
1242
1243 for (src = conn->vhost_lookup_data; src; src = src->next) {
1244 server_addr_rec *sar;
1245
1246 /* We only consider addresses on the name_chain which have a
1247 * matching port.
1248 */
1249 sar = src->sar;
1250 if (sar->host_port != 0 && port != sar->host_port) {
1251 continue;
1252 }
1253
1254 s = src->server;
1255
1256 if (s == last_s) {
1257 /* we've already done a callback for this vhost. */
1258 continue;
1259 }
1260
1261 last_s = s;
1262
1263 rv = func_cb(baton, conn, s);
1264
1265 if (rv != 0) {
1266 break;
1267 }
1268 }
1269 }
1270 else {
1271 rv = func_cb(baton, conn, conn->base_server);
1272 }
1273
1274 return rv;
1275}
1276
1277/* Called for a new connection which has a known local_addr. Note that the
1278 * new connection is assumed to have conn->server == main server.
1279 */
1281{
1284
1285 /* scan the hash table for an exact match first */
1286 trav = find_ipaddr(conn->local_addr);
1287
1288 if (trav) {
1289 /* save the name_chain for later in case this is a name-vhost */
1290 conn->vhost_lookup_data = trav->names;
1291 conn->base_server = trav->server;
1292 return;
1293 }
1294
1295 /* maybe there's a default server or wildcard name-based vhost
1296 * matching this port
1297 */
1298 port = conn->local_addr->port;
1299
1301 if (trav) {
1302 conn->vhost_lookup_data = trav->names;
1303 conn->base_server = trav->server;
1304 return;
1305 }
1306
1307 /* otherwise we're stuck with just the main server
1308 * and no name-based vhosts
1309 */
1310 conn->vhost_lookup_data = NULL;
1311}
Symbol export macros and hook functions.
#define AP_DECLARE_NONSTD(type)
Definition ap_config.h:77
#define AP_DECLARE(type)
Definition ap_config.h:67
const char apr_size_t len
Definition ap_regex.h:187
HANDLE ha
APR general purpose library routines.
APR Strings library.
APR Versioning Interface.
#define APR_VERSION_STRING
APR Standard Headers Support.
return found
Definition core.c:2840
void ap_hook_check_config(ap_HOOK_check_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:96
const char * hostname
request_rec * r
#define HUGE_STRING_LEN
Definition httpd.h:303
#define MAX_STRING_LEN
Definition httpd.h:300
#define OK
Definition httpd.h:456
int ap_exists_config_define(const char *name)
Definition core.c:2896
#define ap_get_core_module_config(v)
Definition http_core.h:383
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_NOTICE
Definition http_log.h:69
#define APLOG_STARTUP
Definition http_log.h:105
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_DEBUG
Definition http_log.h:71
const unsigned char * buf
Definition util_md5.h:50
const char apr_port_t port
Definition http_vhost.h:125
ap_vhost_iterate_conn_cb func_cb
Definition http_vhost.h:86
ap_vhost_iterate_conn_cb void * baton
Definition http_vhost.h:87
void * dummy
Definition http_vhost.h:62
int(* ap_vhost_iterate_conn_cb)(void *baton, conn_rec *conn, server_rec *s)
Definition http_vhost.h:73
const char * host
Definition http_vhost.h:124
void const char * arg
Definition http_vhost.h:63
const char * ap_parse_vhost_addrs(apr_pool_t *p, const char *hostname, server_rec *s)
Definition vhost.c:242
int require_match
Definition http_vhost.h:112
#define APR_EINVAL
Definition apr_errno.h:711
unsigned int count
Definition apr_md5.h:152
apr_file_t * f
apr_bucket apr_bucket_brigade * a
const char * src
Definition apr_encode.h:167
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
apr_redis_t * rc
Definition apr_redis.h:173
#define HTTP_OK
Definition httpd.h:490
#define HTTP_BAD_REQUEST
Definition httpd.h:508
#define ap_strchr(s, c)
Definition httpd.h:2351
int ap_strcasecmp_match(const char *str, const char *expected)
Definition util.c:199
char * ap_get_local_host(apr_pool_t *p)
Definition util.c:2429
char * ap_getword_conf(apr_pool_t *p, const char **line)
Definition util.c:833
apr_size_t size
#define apr_isupper(c)
Definition apr_lib.h:227
#define apr_isdigit(c)
Definition apr_lib.h:209
#define apr_isxdigit(c)
Definition apr_lib.h:229
#define apr_isalpha(c)
Definition apr_lib.h:205
#define apr_tolower(c)
Definition apr_lib.h:231
#define apr_islower(c)
Definition apr_lib.h:213
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_file_t * thefile
const char * key
const struct iovec apr_size_t nvec
int strcasecmp(const char *a, const char *b)
apr_vformatter_buff_t * c
Definition apr_lib.h:175
apr_sockaddr_t * sa
apr_uint16_t apr_port_t
#define APR_UNSPEC
#define APR_INET
char ** scope_id
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
Apache Configuration.
CORE HTTP Daemon.
#define AP_HTTP_CONFORMANCE_UNSAFE
Definition http_core.h:746
Apache Logging library.
Command line options.
HTTP protocol handling.
Virtual Host package.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
#define bad(x)
Definition sdbm.c:50
char * name
apr_port_t port
Definition apr_uri.h:109
char * port_str
Definition apr_uri.h:97
Structure to store things which are per connection.
Definition httpd.h:1152
server_rec * base_server
Definition httpd.h:1156
apr_sockaddr_t * local_addr
Definition httpd.h:1162
void * vhost_lookup_data
Definition httpd.h:1158
server_rec * server
Definition vhost.c:73
server_addr_rec * sar
Definition vhost.c:70
name_chain * initialnames
Definition vhost.c:76
ipaddr_chain * next
Definition vhost.c:69
name_chain * names
Definition vhost.c:74
name_chain * next
Definition vhost.c:58
server_addr_rec * sar
Definition vhost.c:59
server_rec * server
Definition vhost.c:61
A structure that represents the current request.
Definition httpd.h:845
int status
Definition httpd.h:891
char * uri
Definition httpd.h:1016
const char * hostname
Definition httpd.h:883
apr_pool_t * pool
Definition httpd.h:847
apr_uri_t parsed_uri
Definition httpd.h:1092
conn_rec * connection
Definition httpd.h:849
apr_table_t * headers_in
Definition httpd.h:976
server_rec * server
Definition httpd.h:851
A structure to be used for Per-vhost config.
Definition httpd.h:1301
apr_port_t host_port
Definition httpd.h:1309
server_addr_rec * next
Definition httpd.h:1303
char * virthost
Definition httpd.h:1305
apr_sockaddr_t * host_addr
Definition httpd.h:1307
A structure to store information for each virtual server.
Definition httpd.h:1322
struct ap_conf_vector_t * module_config
Definition httpd.h:1341
int ap_matches_request_vhost(request_rec *r, const char *host, apr_port_t port)
Definition vhost.c:953
#define IS_IN6_ANYADDR(ad)
Definition vhost.c:449
static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
Definition vhost.c:698
static int fix_hostname(request_rec *r, const char *host_header, unsigned http_conformance)
Definition vhost.c:828
static name_chain * new_name_chain(apr_pool_t *p, server_rec *s, server_addr_rec *sar)
Definition vhost.c:385
static ipaddr_chain * find_default_server(apr_port_t port)
Definition vhost.c:425
static APR_INLINE unsigned hash_inaddr(unsigned key)
Definition vhost.c:352
void ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
Definition vhost.c:573
static int config_error
Definition vhost.c:103
void ap_init_vhost_config(apr_pool_t *p)
Definition vhost.c:133
static void check_serverpath(request_rec *r)
Definition vhost.c:1093
static APR_INLINE ipaddr_chain * find_ipaddr(apr_sockaddr_t *sa)
Definition vhost.c:398
static ipaddr_chain * default_list
Definition vhost.c:100
static void dump_vhost_config(apr_file_t *f)
Definition vhost.c:513
static ipaddr_chain * iphash_table[256]
Definition vhost.c:94
static int update_server_from_aliases(request_rec *r)
Definition vhost.c:1000
static APR_INLINE const char * construct_host_header(request_rec *r, int is_v6literal)
Definition vhost.c:1135
static const char * get_addresses(apr_pool_t *p, const char *w_, server_addr_rec ***paddr, apr_port_t default_port)
Definition vhost.c:148
int ap_vhost_iterate_given_conn(conn_rec *conn, ap_vhost_iterate_conn_cb func_cb, void *baton)
Definition vhost.c:1229
static ipaddr_chain * new_ipaddr_chain(apr_pool_t *p, server_rec *s, server_addr_rec *sar)
Definition vhost.c:370
int ap_update_vhost_from_headers_ex(request_rec *r, int require_match)
Definition vhost.c:1173
#define IPHASH_TABLE_SIZE
Definition vhost.c:84
static apr_status_t fix_hostname_v6_literal(request_rec *r, char *host)
Definition vhost.c:708
static apr_status_t fix_hostname_non_v6(request_rec *r, char *host)
Definition vhost.c:741
void ap_update_vhost_given_ip(conn_rec *conn)
Definition vhost.c:1280
void ap_update_vhost_from_headers(request_rec *r)
Definition vhost.c:1168
const char * ap_set_name_virtual_host(cmd_parms *cmd, void *dummy, const char *arg)
Definition vhost.c:270
static int matches_aliases(server_rec *s, const char *host)
Definition vhost.c:913
static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
Definition vhost.c:452
static void add_name_vhost_config(apr_pool_t *p, server_rec *main_s, server_rec *s, server_addr_rec *sar, ipaddr_chain *ic)
Definition vhost.c:539
static apr_status_t strict_hostname_check(request_rec *r, char *host)
Definition vhost.c:772
static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
Definition vhost.c:358