httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Querna <>
Subject Vhosts, Listeners and Server_rec, Oh My!
Date Thu, 19 May 2005 23:20:20 GMT
I finally had some time to work on the listen-protocol branch today.

I started moving the accept filter code into its own function, taking a
  pool, a server_rec and a ap_listen_rec.

Seems simple, but the real trick is mapping a single server record to an
ap_listen_rec.  The server_rec provides the protocol, and from that
protocol we can decide how to apply accept filters or tcp defer accept
to the socket.

This mapping from an ap_listen_rec to a server_rec is horrid. Here is
some example code, to find the first listener that matches a server_rec:

some_func(server_rec *s)
    server_rec *ls;
    server_addr_rec *addr;
    ap_listen_rec *lr;

    /* iterate server_rec */
    for (ls = s; ls; ls = ls->next) {
        /* iterate addresses inside the server_rec */
        for (addr = ls->addrs; addr && nfound; addr = addr->next) {
            /* iterate the ap_listeners, see if any match this server */
            for (lr = ap_listeners; lr; lr = lr->next) {
                if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr)
                    && lr->bind_addr->port == addr->host_port) {
                    /* found a match */

The server_rec contains its own list of addresses.  This list doesn't
contain an ap_listen_rec, but its own custom little struct, server_addr_rec.

It gets even worse, just look at server/vhost.c.  It contains the 3rd
place, where we try to map a socket address to a name to a server_rec.
It is also hidden inside private structures, making it much harder to
retrieve this information.  It contains an inverse map, of
server_addr_recs to server_recs.  This is closer to the information that
I need for this task, but I don't think making this interface public or
even CORE_PRIVATE is the best way to proceed.

Radical Change:  One system, not three.  It should contain all the base
server_recs. It should also contain pointers to the ap_listen_rec.  I
don't know what this solution would look like yet, but I think it could
lead to a better system in the long term.

Simple, but a horrible and bad hack: Just add a server_rec* to the
ap_listen_rec, and do the mapping once.

Simpler, but wasteful: Iterate the server_rec in several places.
Iterate the ap_server_rec in several more.  Never get it quite right on
the mappings either.

Further food for thought: Why are name based virtual hosts in the
server/vhost.c?  I think they should belong in modules/http/*.c.

I welcome alternative ideas.  Doing a radical change in how virtual
hosts are mapped might have a significant impart in many parts of the
code, and should not be taken lightly.


View raw message