Commit 1ef5eb7d authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Use 2 sep hashing functions to account for collisions...

Safe enough

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1208897 13f79535-47bb-0310-9956-ffa450edef68
parent b28ad81a
Loading
Loading
Loading
Loading
+6 −2
Changes for modules/proxy/mod_proxy.c: 6 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -2428,8 +2428,10 @@ static void child_init(apr_pool_t *p, server_rec *s)
            PROXY_STRNCPY(conf->forward->s->name,     "proxy:forward");
            PROXY_STRNCPY(conf->forward->s->hostname, "*");
            PROXY_STRNCPY(conf->forward->s->scheme,   "*");
            conf->forward->hash = conf->forward->s->hash =
            conf->forward->hash.def = conf->forward->s->hash.def =
                ap_proxy_hashfunc(conf->forward->s->name, PROXY_HASHFUNC_DEFAULT);
             conf->forward->hash.fnv = conf->forward->s->hash.fnv =
                ap_proxy_hashfunc(conf->forward->s->name, PROXY_HASHFUNC_FNV);
            /* Do not disable worker in case of errors */
            conf->forward->s->status |= PROXY_WORKER_IGNORE_ERRORS;
            /* Disable address cache for generic forward worker */
@@ -2441,8 +2443,10 @@ static void child_init(apr_pool_t *p, server_rec *s)
            PROXY_STRNCPY(reverse->s->name,     "proxy:reverse");
            PROXY_STRNCPY(reverse->s->hostname, "*");
            PROXY_STRNCPY(reverse->s->scheme,   "*");
            reverse->hash = reverse->s->hash =
            reverse->hash.def = reverse->s->hash.def =
                ap_proxy_hashfunc(reverse->s->name, PROXY_HASHFUNC_DEFAULT);
            reverse->hash.fnv = reverse->s->hash.fnv =
                ap_proxy_hashfunc(reverse->s->name, PROXY_HASHFUNC_FNV);
            /* Do not disable worker in case of errors */
            reverse->s->status |= PROXY_WORKER_IGNORE_ERRORS;
            /* Disable address cache for generic reverse worker */
+9 −4
Changes for modules/proxy/mod_proxy.h: 9 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -320,6 +320,11 @@ do { \
(w)->s->io_buffer_size_set   = (c)->io_buffer_size_set;    \
} while (0)

/* use 2 hashes */
typedef struct {
    unsigned int def;
    unsigned int fnv;
} proxy_hashes ;

/* Runtime worker status informations. Shared in scoreboard */
typedef struct {
@@ -338,7 +343,7 @@ typedef struct {
    int             hmax;       /* Hard maximum on the total number of connections */
    int             flush_wait; /* poll wait time in microseconds if flush_auto */
    int             index;      /* shm array index */
    unsigned int    hash;       /* hash of worker name */
    proxy_hashes    hash;       /* hash of worker name */
    unsigned int    status;     /* worker status bitfield */
    enum {
        flush_off,
@@ -381,7 +386,7 @@ typedef struct {

/* Worker configuration */
struct proxy_worker {
    unsigned int    hash;       /* hash of worker name */
    proxy_hashes    hash;       /* hash of worker name */
    unsigned int local_status;  /* status of per-process worker */
    proxy_conn_pool     *cp;    /* Connection pool to use */
    proxy_worker_shared   *s;   /* Shared data */
@@ -409,7 +414,7 @@ typedef struct {
    apr_time_t      wupdated;     /* timestamp of last change to workers list */
    int             max_attempts;     /* Number of attempts before failing */
    int             index;      /* shm array index */
    unsigned int hash;
    proxy_hashes hash;
    unsigned int    sticky_force:1;   /* Disable failover for sticky sessions */
    unsigned int    scolonsep:1;      /* true if ';' seps sticky session paths */
    unsigned int    max_attempts_set:1;
@@ -428,7 +433,7 @@ struct proxy_balancer {
    ap_slotmem_provider_t *storage;
    int growth;                   /* number of post-config workers can added */
    int max_workers;              /* maximum number of allowed workers */
    unsigned int hash;
    proxy_hashes hash;
    apr_time_t      wupdated;    /* timestamp of last change to workers list */
    proxy_balancer_method *lbmethod;
    apr_global_mutex_t  *gmutex; /* global lock for updating list of workers */
+10 −7
Changes for modules/proxy/proxy_util.c: 10 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -1298,7 +1298,7 @@ PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
    proxy_balancer *balancer;
    char *c, *uri = apr_pstrdup(p, url);
    int i;
    unsigned int hash;
    proxy_hashes hash;

    ap_str_tolower(uri);
    c = strchr(uri, ':');
@@ -1309,10 +1309,11 @@ PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
    if ((c = strchr(c + 3, '/'))) {
        *c = '\0';
    }
    hash = ap_proxy_hashfunc(uri, PROXY_HASHFUNC_DEFAULT);
    hash.def = ap_proxy_hashfunc(uri, PROXY_HASHFUNC_DEFAULT);
    hash.fnv = ap_proxy_hashfunc(uri, PROXY_HASHFUNC_FNV);
    balancer = (proxy_balancer *)conf->balancers->elts;
    for (i = 0; i < conf->balancers->nelts; i++) {
        if (balancer->hash == hash) {
        if (balancer->hash.def == hash.def && balancer->hash.fnv == hash.fnv) {
            if (!care || !balancer->s->inactive) {
                return balancer;
            }
@@ -1401,7 +1402,8 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
    if (PROXY_STRNCPY(bshared->sname, sname) != APR_SUCCESS) {
        return apr_psprintf(p, "balancer safe-name (%s) too long", sname);
    }
    bshared->hash = ap_proxy_hashfunc(bshared->name, PROXY_HASHFUNC_DEFAULT);    
    bshared->hash.def = ap_proxy_hashfunc(bshared->name, PROXY_HASHFUNC_DEFAULT);
    bshared->hash.fnv = ap_proxy_hashfunc(bshared->name, PROXY_HASHFUNC_FNV);
    (*balancer)->hash = bshared->hash;

    /* Retrieve a UUID and store the nonce for the lifetime of
@@ -1835,7 +1837,8 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
    wshared->is_address_reusable = 1;
    wshared->lbfactor = 1;
    wshared->smax = -1;
    wshared->hash = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_DEFAULT);
    wshared->hash.def = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_DEFAULT);
    wshared->hash.fnv = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_FNV);
    wshared->was_malloced = (do_malloc != 0);

    (*worker)->hash = wshared->hash;
@@ -2985,13 +2988,13 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec
        /* account for possible "holes" in the slotmem
         * (eg: slots 0-2 are used, but 3 isn't, but 4-5 is)
         */
        if (!shm->hash)
        if (!shm->hash.def || !shm->hash.fnv)
            continue;
        found = 0;
        workers = (proxy_worker **)b->workers->elts;
        for (i = 0; i < b->workers->nelts; i++, workers++) {
            proxy_worker *worker = *workers;
            if (worker->hash == shm->hash) {
            if (worker->hash.def == shm->hash.def && worker->hash.fnv == shm->hash.fnv) {
                found = 1;
                break;
            }