return NULL;
}
-static void dump_vhost_config(apr_file_t *f)
+static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
{
- int i;
- ipaddr_chain *ic;
name_chain *nc;
+ int len;
char buf[MAX_STRING_LEN];
+ if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
+ len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
+ ic->sar->host_port);
+ }
+ else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
+ len = apr_snprintf(buf, sizeof(buf), "*:%u",
+ ic->sar->host_port);
+ }
+ else {
+ len = apr_snprintf(buf, sizeof(buf), "%pA:%u",
+ &ic->sar->host_addr, ic->sar->host_port);
+ }
+ if (ic->sar->host_port == 0) {
+ buf[len-1] = '*';
+ }
+ if (ic->names == NULL) {
+ apr_fprintf(f, "%-22s %s (%s:%u)\n", buf, ic->server->server_hostname,
+ ic->server->defn_name, ic->server->defn_line_number);
+ return;
+ }
+ apr_fprintf(f, "%-22s is a NameVirtualHost\n"
+ "%22s default server %s (%s:%u)\n",
+ buf, "", ic->server->server_hostname,
+ ic->server->defn_name, ic->server->defn_line_number);
+ for (nc = ic->names; nc; nc = nc->next) {
+ if (nc->sar->host_port) {
+ apr_fprintf(f, "%22s port %u ", "", nc->sar->host_port);
+ }
+ else {
+ apr_fprintf(f, "%22s port * ", "");
+ }
+ apr_fprintf(f, "namevhost %s (%s:%u)\n", nc->server->server_hostname,
+ nc->server->defn_name, nc->server->defn_line_number);
+ }
+}
+
+static void dump_vhost_config(apr_file_t *f)
+{
+ ipaddr_chain *ic;
+ int i;
+
apr_fprintf(f, "VirtualHost configuration:\n");
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
for (ic = iphash_table[i]; ic; ic = ic->next) {
- if (ic->sar->host_port == 0) {
- apr_snprintf(buf, sizeof(buf), "%pA:*", &ic->sar->host_addr);
- }
- else {
- apr_snprintf(buf, sizeof(buf), "%pA:%u", &ic->sar->host_addr,
- ic->sar->host_port);
- }
- if (ic->names == NULL) {
- apr_fprintf(f, "%-22s %s (%s:%u)\n", buf,
- ic->server->server_hostname, ic->server->defn_name,
- ic->server->defn_line_number);
- continue;
- }
- apr_fprintf(f, "%-22s is a NameVirtualHost\n"
- "%22s default server %s (%s:%u)\n",
- buf, "", ic->server->server_hostname,
- ic->server->defn_name, ic->server->defn_line_number);
- for (nc = ic->names; nc; nc = nc->next) {
- if (nc->sar->host_port) {
- apr_fprintf(f, "%22s port %u ", "", nc->sar->host_port);
- }
- else {
- apr_fprintf(f, "%22s port * ", "");
- }
- apr_fprintf(f, "namevhost %s (%s:%u)\n",
- nc->server->server_hostname,
- nc->server->defn_name,
- nc->server->defn_line_number);
- }
+ dump_a_vhost(f, ic);
}
}
if (default_list) {
- apr_fprintf(f, "_default_ servers:\n");
+ apr_fprintf(f, "wildcard NameVirtualHosts and _default_ servers:\n");
for (ic = default_list; ic; ic = ic->next) {
- if (ic->sar->host_port == 0) {
- apr_fprintf(f, "port * ");
- }
- else {
- apr_fprintf(f, "port %u ", ic->sar->host_port);
- }
- apr_fprintf(f, "server %s (%s:%u)\n",
- ic->server->server_hostname, ic->server->defn_name,
- ic->server->defn_line_number);
+ dump_a_vhost(f, ic);
+ }
+ }
+}
+
+/*
+ * Two helper functions for ap_fini_vhost_config()
+ */
+static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s, server_rec *s,
+ server_addr_rec *sar, ipaddr_chain *ic)
+{
+ /* the first time we encounter a NameVirtualHost address
+ * ic->server will be NULL, on subsequent encounters
+ * ic->names will be non-NULL.
+ */
+ if (ic->names || ic->server == NULL) {
+ name_chain *nc = new_name_chain(p, s, sar);
+ nc->next = ic->names;
+ ic->names = nc;
+ ic->server = s;
+ if (sar->host_port != ic->sar->host_port) {
+ /* one of the two is a * port, the other isn't */
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
+ "VirtualHost %s:%u -- mixing * "
+ "ports and non-* ports with "
+ "a NameVirtualHost address is not supported,"
+ " proceeding with undefined results",
+ sar->virthost, sar->host_port);
+ }
+ return 1;
+ }
+ else {
+ /* IP-based vhosts are handled by the caller */
+ return 0;
+ }
+}
+
+static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic)
+{
+ while (*pic) {
+ ipaddr_chain *ic = *pic;
+
+ if (ic->server == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
+ "NameVirtualHost %s:%u has no VirtualHosts",
+ ic->sar->virthost, ic->sar->host_port);
+ *pic = ic->next;
+ }
+ else if (ic->names == NULL) {
+ /* if server != NULL and names == NULL then we're done
+ * looking at NameVirtualHosts
+ */
+ break;
+ }
+ else {
+ pic = &ic->next;
}
}
}
*/
for (sar = name_vhost_list; sar; sar = sar->next) {
unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
- ipaddr_chain *new = new_ipaddr_chain(p, NULL, sar);
-
- *iphash_table_tail[bucket] = new;
- iphash_table_tail[bucket] = &new->next;
+ ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
+ if (sar->host_addr.s_addr != INADDR_ANY) {
+ *iphash_table_tail[bucket] = ic;
+ iphash_table_tail[bucket] = &ic->next;
+ }
+ else {
+ /* A wildcard NameVirtualHost goes on the default_list so
+ * that it can catch incoming requests on any address.
+ */
+ ic->next = default_list;
+ default_list = ic;
+ }
/* Notice that what we've done is insert an ipaddr_chain with
- * both server and names NULL. Remember that.
+ * both server and names NULL. This fact is used to spot name-
+ * based vhosts in add_name_vhost_config().
*/
}
if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
|| sar->host_addr.s_addr == INADDR_ANY) {
- /* add it to default bucket for each appropriate sar
- * since we need to do a port test
- */
- ipaddr_chain *other;
-
- other = find_default_server(sar->host_port);
- if (other && other->sar->host_port != 0) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
- "_default_ VirtualHost overlap on port %u,"
+ ic = find_default_server(sar->host_port);
+ if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
+ if (ic && ic->sar->host_port != 0) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
+ 0, main_s, "_default_ VirtualHost overlap on port %u,"
" the first has precedence", sar->host_port);
+ }
+ ic = new_ipaddr_chain(p, s, sar);
+ ic->next = default_list;
+ default_list = ic;
}
has_default_vhost_addr = 1;
- ic = new_ipaddr_chain(p, s, sar);
- ic->next = default_list;
- default_list = ic;
}
else {
/* see if it matches something we've already got */
ic = find_ipaddr(&sar->host_addr, sar->host_port);
- /* the first time we encounter a NameVirtualHost address
- * ic->server will be NULL, on subsequent encounters
- * ic->names will be non-NULL.
- */
- if (ic && (ic->names || ic->server == NULL)) {
- name_chain *nc = new_name_chain(p, s, sar);
- nc->next = ic->names;
- ic->names = nc;
- ic->server = s;
- if (sar->host_port != ic->sar->host_port) {
- /* one of the two is a * port, the other isn't */
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
- "VirtualHost %s:%u -- mixing * "
- "ports and non-* ports with "
- "a NameVirtualHost address is not supported,"
- " proceeding with undefined results",
- sar->virthost, sar->host_port);
- }
+ if (!ic) {
+ unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
+
+ ic = new_ipaddr_chain(p, s, sar);
+ ic->next = *iphash_table_tail[bucket];
+ *iphash_table_tail[bucket] = ic;
}
- else if (ic) {
+ else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
"VirtualHost %s:%u overlaps with "
"VirtualHost %s:%u, the first has precedence, "
ic->sar = sar;
ic->server = s;
}
- else {
- unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
-
- ic = new_ipaddr_chain(p, s, sar);
- ic->next = *iphash_table_tail[bucket];
- *iphash_table_tail[bucket] = ic;
- }
}
}
* hosts associated with them. Lamers.
*/
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
- ipaddr_chain **pic = &iphash_table[i];
-
- while (*pic) {
- ipaddr_chain *ic = *pic;
-
- if (ic->server == NULL) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
- "NameVirtualHost %s:%u has no VirtualHosts",
- ic->sar->virthost, ic->sar->host_port);
- *pic = ic->next;
- }
- else if (ic->names == NULL) {
- /* if server != NULL and names == NULL then we're done
- * looking at NameVirtualHosts
- */
- break;
- }
- else {
- pic = &ic->next;
- }
- }
+ remove_unused_name_vhosts(main_s, &iphash_table[i]);
}
+ remove_unused_name_vhosts(main_s, &default_list);
#ifdef IPHASH_STATISTICS
dump_iphash_statistics(main_s);
return;
}
- /* There's certainly no name-vhosts with this address, they would have
- * been matched above.
+ /* maybe there's a default server or wildcard name-based vhost
+ * matching this port
*/
- conn->vhost_lookup_data = NULL;
-
- /* maybe there's a default server matching this port */
trav = find_default_server(port);
if (trav) {
+ conn->vhost_lookup_data = trav->names;
conn->base_server = trav->server;
+ return;
}
- /* otherwise we're stuck with just the main server */
+ /* otherwise we're stuck with just the main server
+ * and no name-based vhosts
+ */
+ conn->vhost_lookup_data = NULL;
}