On 1 Feb 2018, at 17:54, Yann Ylavic <ylavic....@gmail.com> wrote:
> 
> I have this patch (attached) floating around that allows users to
> configure a *fixed* UID for each vhost.
> 
> There are several places where we need an ID for vhosts, and where we
> compute one based on ServerName/Port, addresses, configuration path
> and line numbers, ...
> This UID could be used instead, moreover since it has the property to
> not change on (re)starts we can also use it for things bound to a
> vhost regardless of the startup and unrelated configuration changes
> (the attached patch uses it for SHMs in mod_proxy_balancer, as an
> example).
> 
> If no ServerUID is configured, I _think_ we can compute one too,
> better than the one usually computed in our code since it won't change
> unless address(es)/port(s) or ServerName of the vhost changes (which
> is not a "light" change anyway).
> In any case the patch also handles collisions, if ever...
> So for this what the patch does is (with rationale in comment):
> 
> +    int i, *num;
> +    apr_hash_t *servers_uids = apr_hash_make(p);
> []
> +        if (!s->server_uid) {
> +            server_addr_rec *addr;
> +            apr_md5_ctx_t md5_ctx;
> +            unsigned char md5[APR_MD5_DIGESTSIZE];
> +
> +            /* Assumes the unique identifier of a vhost is its address(es)
> +             * plus the ServerName:Port. Should two or more vhosts have this
> +             * same identifier, the first one would always be elected to
> +             * handle the requests, so this shouldn't be an issue...
> +             */
> +            apr_md5_init(&md5_ctx);
> +            for (addr = s->addrs; addr; addr = addr->next) {
> +                char host_ip[64]; /* for any IPv[46] string */
> +                apr_sockaddr_ip_getbuf(host_ip, sizeof host_ip,
> +                                       addr->host_addr);
> +                apr_md5_update(&md5_ctx, (unsigned char *)host_ip,
> +                                         strlen(host_ip));
> +                apr_md5_update(&md5_ctx, (unsigned char *)&addr->host_port,
> +                                         sizeof(addr->host_port));
> +            }
> +            apr_md5_update(&md5_ctx, (unsigned char *)s->server_hostname,
> +                                     strlen(s->server_hostname));
> +            apr_md5_update(&md5_ctx, (unsigned char *)&s->port,
> +                                     sizeof(s->port));
> +            apr_md5_final(md5, &md5_ctx);
> +
> +            s->server_uid = apr_pescape_hex(p, md5, sizeof md5, 0);
> +        }
> +        /* Handle collisions, that's Unique ID! */
> +        num = apr_hash_get(servers_uids, s->server_uid,
> +                           APR_HASH_KEY_STRING);
> +        if (num) {
> +            ++*num;
> +            s->server_uid = apr_psprintf(p, "%s_%i", s->server_uid, *num);
> +        }
> +        else {
> +            num = apr_pcalloc(p, sizeof *num);
> +            apr_hash_set(servers_uids, s->server_uid,
> +                         APR_HASH_KEY_STRING, num);
> +        }
> (Rest attached)
> 
> WDYT?

I am surprised httpd doesn’t already have this, considering the fundamental 
role of the virtualhost container.  

- Mark

Reply via email to