]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: spoe: Use a different engine-id per process
authorKevin Zhu <ipandtcp@gmail.com>
Tue, 17 Sep 2019 13:05:45 +0000 (15:05 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 26 Sep 2019 14:51:02 +0000 (16:51 +0200)
SPOE engine-id is the same for all processes when nbproc is more than 1. So, in
async mode, an agent receiving a NOTIFY frame from a process may send the ACK to
another process. It is abviously wrong. A different engine-id must be generated
for each process.

This patch must be backported to 2.0, 1.9 and 1.8.

src/flt_spoe.c

index b8323f60c6be32158774483f59bb04fed990bb22..f0047d4d9444a5541e80cea339d8d9aad7fb0ee7 100644 (file)
@@ -267,7 +267,7 @@ generate_pseudo_uuid()
                return NULL;
 
        if (!init) {
-               srand(now_ms);
+               srand(now_ms * pid);
                init = 1;
        }
 
@@ -3111,6 +3111,22 @@ spoe_check(struct proxy *px, struct flt_conf *fconf)
        return 0;
 }
 
+/* Initializes the SPOE filter for a proxy for a specific thread.
+ * Returns a negative value if an error occurs. */
+static int
+spoe_init_per_thread(struct proxy *p, struct flt_conf *fconf)
+{
+       struct spoe_config *conf = fconf->conf;
+       struct spoe_agent *agent = conf->agent;
+
+       if (agent->engine_id == NULL) {
+               agent->engine_id = generate_pseudo_uuid();
+               if (agent->engine_id == NULL)
+                       return -1;
+       }
+       return 0;
+}
+
 /**************************************************************************
  * Hooks attached to a stream
  *************************************************************************/
@@ -3309,6 +3325,7 @@ struct flt_ops spoe_ops = {
        .init   = spoe_init,
        .deinit = spoe_deinit,
        .check  = spoe_check,
+       .init_per_thread = spoe_init_per_thread,
 
        /* Handle start/stop of SPOE */
        .attach         = spoe_start,
@@ -4177,8 +4194,6 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
                }
                curagent->var_pfx = strdup(curagent->id);
        }
-       if (curagent->engine_id == NULL)
-               curagent->engine_id = generate_pseudo_uuid();
 
        if (curagent->var_on_error) {
                struct arg arg;