~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to server/vhost.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

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