BUG/MEDIUM: spoe: Use a different engine-id per process

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.
This commit is contained in:
Kevin Zhu 2019-09-17 15:05:45 +02:00 committed by Christopher Faulet
parent eec96b5381
commit d87b1a56d5

View File

@ -267,7 +267,7 @@ generate_pseudo_uuid()
return NULL; return NULL;
if (!init) { if (!init) {
srand(now_ms); srand(now_ms * pid);
init = 1; init = 1;
} }
@ -3111,6 +3111,22 @@ spoe_check(struct proxy *px, struct flt_conf *fconf)
return 0; 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 * Hooks attached to a stream
*************************************************************************/ *************************************************************************/
@ -3309,6 +3325,7 @@ struct flt_ops spoe_ops = {
.init = spoe_init, .init = spoe_init,
.deinit = spoe_deinit, .deinit = spoe_deinit,
.check = spoe_check, .check = spoe_check,
.init_per_thread = spoe_init_per_thread,
/* Handle start/stop of SPOE */ /* Handle start/stop of SPOE */
.attach = spoe_start, .attach = spoe_start,
@ -4177,8 +4194,6 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
} }
curagent->var_pfx = strdup(curagent->id); curagent->var_pfx = strdup(curagent->id);
} }
if (curagent->engine_id == NULL)
curagent->engine_id = generate_pseudo_uuid();
if (curagent->var_on_error) { if (curagent->var_on_error) {
struct arg arg; struct arg arg;