--- mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c	2013-11-22 15:49:17.136121139 +0100
+++ mod_cluster/native/mod_proxy_cluster/mod_proxy_cluster.c	2013-11-22 16:27:28.711196632 +0100
@@ -35,6 +35,7 @@
 #include "http_request.h"
 #include "http_protocol.h"
 #include "http_core.h"
+#include "scoreboard.h"
 #include "ap_mpm.h"
 #include "mod_proxy.h"
 
@@ -532,7 +533,7 @@
     }
 
     /* prevent other threads using it */
-    worker->s->status = worker->s->status |= PROXY_WORKER_IN_ERROR;
+    worker->s->status = worker->s->status | PROXY_WORKER_IN_ERROR;
 
     /* apr_reslist_acquired_count */
     i = 0;
@@ -664,6 +665,22 @@
     }
     return NULL;
 }
+/* read the node and check that it corresponds to the worker */
+static apr_status_t read_node_worker(int id, nodeinfo_t **node, proxy_worker *worker)
+{
+    char sport[7];
+    apr_status_t status = node_storage->read_node(id, node);
+    if (status != APR_SUCCESS)
+        return status;
+    apr_snprintf(sport, sizeof(sport), "%d", worker->port);
+    if (strcmp(worker->scheme, (* node)->mess.Type) ||
+        strcmp(worker->hostname, (* node)->mess.Host) ||
+        strcmp(sport, (* node)->mess.Port)) {
+        /* for some reasons it is not the right node */
+        return APR_NOTFOUND;
+    }
+    return APR_SUCCESS;
+}
 static void update_workers_lbstatus(proxy_server_conf *conf, apr_pool_t *pool, server_rec *server)
 {
     int *id, size, i;
@@ -704,11 +721,22 @@
                 apr_status_t rv;
                 apr_pool_t *rrp;
                 request_rec *rnew;
-                proxy_worker *worker = get_worker_from_id(conf, id[i], stat);
+                proxy_worker *worker;
+                apr_thread_mutex_lock(lock);
+                worker = get_worker_from_id(conf, id[i], stat);
+                apr_thread_mutex_unlock(lock);
                 if (worker == NULL)
                     continue; /* skip it */
-                apr_snprintf(sport, sizeof(sport), ":%d", worker->port);
-                url = apr_pstrcat(pool, worker->scheme, "://", worker->hostname,  sport, "/", NULL);
+                apr_snprintf(sport, sizeof(sport), "%d", worker->port);
+                if (strcmp(worker->scheme, ou->mess.Type) ||
+                    strcmp(worker->hostname, ou->mess.Host) ||
+                    strcmp(sport, ou->mess.Port)) {
+                    /* the worker doesn't correspond to the node */
+                    worker->id = 0;
+                    ap_my_generation--; /* mark old generation that will recreate the process */ 
+                    continue; /* skip it */
+                }
+                url = apr_pstrcat(pool, worker->scheme, "://", worker->hostname, ":", sport, "/", NULL);
 
                 apr_pool_create(&rrp, pool);
                 apr_pool_tag(rrp, "subrequest");
@@ -725,6 +753,10 @@
 
                 worker->s->error_time = 0; /* Force retry now */
                 rv = proxy_cluster_try_pingpong(rnew, worker, url, conf, ou->mess.ping, ou->mess.timeout);
+
+                if (read_node_worker(id[i], &ou, worker) != APR_SUCCESS)
+                    continue;
+
                 if (rv != APR_SUCCESS) {
                     /* We can't reach the node */
                     worker->s->status |= PROXY_WORKER_IN_ERROR;
@@ -1041,7 +1073,6 @@
         /* keep only the contexts corresponding to our balancer */
         if (balancer != NULL) {
             nodeinfo_t *node;
-            char *name;
             if (node_storage->read_node(context->node, &node) != APR_SUCCESS)
                 continue;
             if (strlen(balancer->name) > 11 && strcasecmp(&balancer->name[11], node->mess.balancer) != 0)
@@ -1113,7 +1144,6 @@
         return NULL;
     while (*nodes != -1) {
         nodeinfo_t *node;
-        char *ret;
         if (node_storage->read_node(*nodes, &node) != APR_SUCCESS) {
             nodes++;
             continue;
@@ -1227,7 +1257,7 @@
              * not in error state or not disabled.
              * and that can map the context.
              */
-            if (node_storage->read_node(worker->id, &node) != APR_SUCCESS)
+            if (read_node_worker(worker->id, &node, worker) != APR_SUCCESS)
                 continue; /* Can't read node */
 
             if (PROXY_WORKER_IS_USABLE(worker) && iscontext_host_ok(r, balancer, worker->id)) {
@@ -1247,7 +1277,7 @@
                         nodeinfo_t *node1;
                         int lbstatus, lbstatus1;
 
-                        if (node_storage->read_node(mycandidate->id, &node1) != APR_SUCCESS)
+                        if (read_node_worker(mycandidate->id, &node1, mycandidate) != APR_SUCCESS)
                             continue;
                         lbstatus1 = ((mycandidate->s->elected - node1->mess.oldelected) * 1000)/mycandidate->s->lbfactor;
                         lbstatus  = ((worker->s->elected - node->mess.oldelected) * 1000)/worker->s->lbfactor;
@@ -1522,6 +1552,18 @@
         for (i = 0; i < conf->workers->nelts; i++, ptr=ptr+sizew) {
             worker = (proxy_worker *)ptr;
             if (worker->id == id && worker->s == stat) {
+
+                /* Check that the worker is really the one we need */
+                char sport[7];
+                apr_snprintf(sport, sizeof(sport), "%d", worker->port);
+                if (strcmp(worker->scheme, node->mess.Type) ||
+                    strcmp(worker->hostname, node->mess.Host) ||
+                    strcmp(sport, node->mess.Port)) {
+                    worker->id = 0;
+                    ap_my_generation--; /* mark old generation that will recreate the process */
+                    continue; /* skip it */
+                }
+
                 foundid = id;
                 break;
             }
@@ -2130,7 +2172,6 @@
     checking_standby = checked_standby = 0;
     while (!checked_standby) {
         char *ptr = balancer->workers->elts;
-        worker = (proxy_worker *)balancer->workers->elts;
         for (i = 0; i < balancer->workers->nelts; i++, ptr=ptr+sizew) {
             worker = (proxy_worker *)ptr;
             if (worker->id == 0)
@@ -2143,8 +2184,8 @@
                 if (worker && PROXY_WORKER_IS_USABLE(worker)) {
                     /* The context may not be available */
                     nodeinfo_t *node;
-                    if (node_storage->read_node(worker->id, &node) != APR_SUCCESS)
-                        return NULL; /* can't read node */
+                    if (read_node_worker(worker->id, &node, worker) != APR_SUCCESS)
+                       continue;
                     if (iscontext_host_ok(r, balancer, worker->id))
                        return worker;
                     else
