Hi Christopher

SPOE engine-id is all same when nbproc is more than 1, the clients all
group under same engine, and same stream-id and frame-id frames may come at
same time. So we alway need engine-id to identify client's and frames.
Best Regards
From caedabe336897704b4da39818ac7d226c7b8a9db Mon Sep 17 00:00:00 2001
From: Kevin Zhu <ipand...@gmail.com>
Date: Mon, 2 Sep 2019 13:45:34 +0800
Subject: [PATCH] BUG/MEDIUM: spoe: engine-id is necessary if not health check

SPOE engine-id is all same when nbproc is more than 1, the clients all
group under same engine, and same stream-id and frame-id frames may come at
same time. So we alway need engine-id to identify client's and frames.
---
 doc/SPOE.txt   |  8 ++++----
 src/flt_spoe.c | 35 +++++++++++++++++++++++++----------
 2 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/doc/SPOE.txt b/doc/SPOE.txt
index 19f00ad..dd8f920 100644
--- a/doc/SPOE.txt
+++ b/doc/SPOE.txt
@@ -932,6 +932,10 @@ Following items are mandatory in the KV-LIST:
     This a comma-separated list of capabilities supported by HAProxy. Spaces
     must be ignored, if any.
 
+  * "engine-id"    <STRING>
+
+    This is a uniq string that identify a SPOE engine.
+
 Following optional items can be added in the KV-LIST:
 
   * "healthcheck"    <BOOLEAN>
@@ -939,10 +943,6 @@ Following optional items can be added in the KV-LIST:
     If this item is set to TRUE, then the HAPROXY-HELLO frame is sent during a
     SPOE health check. When set to FALSE, this item can be ignored.
 
-  * "engine-id"    <STRING>
-
-    This is a uniq string that identify a SPOE engine.
-
 To finish the HELLO handshake, the agent must return an AGENT-HELLO frame with
 its supported SPOP version, the lower value between its maximum size allowed
 for a frame and the HAProxy one and capabilities it supports. If an error
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
index b8323f6..06ceeae 100644
--- a/src/flt_spoe.c
+++ b/src/flt_spoe.c
@@ -267,7 +267,7 @@ generate_pseudo_uuid()
 		return NULL;
 
 	if (!init) {
-		srand(now_ms);
+		srand(now_ms + pid);
 		init = 1;
 	}
 
@@ -457,17 +457,18 @@ spoe_prepare_hahello_frame(struct appctx *appctx, char *frame, size_t size)
 	if (spoe_encode_buffer(chk->area, chk->data, &p, end) == -1)
 		goto too_big;
 
-	/* (optionnal) "engine-id" K/V item, if present */
-	if (agent != NULL && agent->engine_id != NULL) {
-		sz = SLEN(ENGINE_ID_KEY);
-		if (spoe_encode_buffer(ENGINE_ID_KEY, sz, &p, end) == -1)
-			goto too_big;
+	/* "engine-id" K/V item */
+	sz = SLEN(ENGINE_ID_KEY);
+	if (spoe_encode_buffer(ENGINE_ID_KEY, sz, &p, end) == -1)
+		goto too_big;
 
-		*p++ = SPOE_DATA_T_STR;
+	*p++ = SPOE_DATA_T_STR;
+	if (agent != NULL) {
 		sz = strlen(agent->engine_id);
 		if (spoe_encode_buffer(agent->engine_id, sz, &p, end) == -1)
 			goto too_big;
-	}
+	} else if (spoe_encode_buffer(NULL, 0, &p, end) == -1)
+		goto too_big;
 
 	return (p - frame);
 
@@ -3111,6 +3112,21 @@ 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_agent *agent = ((struct spoe_config*)fconf->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;
-- 
2.7.4

Reply via email to