MEDIUM: spoe: Parse new "spoe-group" section in SPOE config file
For now, this section is only parsed. It should have the following format:
spoe-group <grp-name>
messages <msg-name> ...
And then SPOE groups must be referenced in spoe-agent section:
spoe-agnt <name>
...
groups <grp-name> ...
The purpose of these groups is to trigger messages sending from TCP or HTTP
rules, directly from HAProxy configuration, and not on specific event. This part
will be added in another patch.
It is important to note that a message belongs at most to a group.
diff --git a/doc/SPOE.txt b/doc/SPOE.txt
index 48cfa02..7f38068 100644
--- a/doc/SPOE.txt
+++ b/doc/SPOE.txt
@@ -16,7 +16,8 @@
2.1. SPOE scope
2.2. "spoe-agent" section
2.3. "spoe-message" section
- 2.4. Example
+ 2.4. "spoe-group" section
+ 2.5. Example
3. SPOP specification
3.1. Data types
3.2. Frames
@@ -99,9 +100,8 @@
reserved to SPOE. This is also a way to keep the HAProxy configuration clean.
A SPOE configuration file must contains, at least, the SPOA configuration
-("spoe-agent" section) and SPOE messages ("spoe-message" section) attached to
-this agent. Unused messages (not reference in "spoe-agent" section) will be
-ignored.
+("spoe-agent" section) and SPOE messages/groups ("spoe-message" or "spoe-group"
+sections) attached to this agent.
IMPORTANT : The configuration of a SPOE filter must be located in a dedicated
file. But the backend used by a SPOA must be declared in HAProxy configuration
@@ -114,8 +114,8 @@
scope in the SPOE configuration with the same name. You can have several SPOE
scope in the same file. In each scope, you must define one and only one
"spoe-agent" section to configure the SPOA linked to your SPOE and several
-"spoe-message" sections to describe messages sent to servers mananged by your
-SPOA.
+"spoe-message" and "spoe-group" sections to describe, respecively, messages and
+group of messages sent to servers mananged by your SPOA.
A SPOE scope starts with this kind of line :
@@ -132,6 +132,10 @@
...
spoe-message msg2
...
+ spoe-group grp1
+ ...
+ spoe-group grp2
+ ...
[my-second-engine]
...
@@ -159,6 +163,7 @@
<name> is the name of the agent section.
following keywords are supported :
+ - groups
- maxconnrate
- maxerrrate
- max-frame-size
@@ -173,6 +178,18 @@
- use-backend
+groups <grp-name> ...
+ Declare the list of SPOE groups that an agent will handle.
+
+ Arguments :
+ <grp-name> is the name of a SPOE group.
+
+ Groups delcared here must be found in the same engine scope, else an error is
+ triggered during the configuration parsing. You can have many "groups" lines.
+
+ See also: "spoe-group" section.
+
+
maxconnrate <number>
Set the maximum number of connections per second to <number>. The SPOE will
stop to open new connections if the maximum is reached and will wait to
@@ -407,7 +424,42 @@
See section "Events & Messages" for more details about supported events.
See section 7 about ACL usage in the HAProxy Configuration Manual.
+2.4. "spoe-group" section
+--------------------------
+
+This section can be used to declare a group of SPOE messages. Unlike messages
+referenced in a "spoe-agent" section, messages inside a group are not sent on a
+specific event. The sending must be triggered by TCP or HTTP rules, from the
+HAProxy configuration.
+
+
+spoe-group <name>
+ Create a new SPOE group with the name <name>.
+
+ Arguments :
+ <name> is the name of the SPOE group.
+
+ Here you define a group of SPOE messages that can be referenced in a
+ "spoe-agent" section. Following keywords are supported :
+ - messages
+
+ See also: "spoe-agent" and "spoe-message" sections.
+
+
+messages <msg-name> ...
+ Declare the list of SPOE messages belonging to the group.
+
+ Arguments :
+ <msg-name> is the name of a SPOE message.
+
+ Messages declared here must be found in the same engine scope, else an error
+ is triggered during the configuration parsing. Furthermore, a message belongs
+ at most to a group. You can have many "messages" lines.
+
+ See also: "spoe-message" section.
+
+
-2.4. Example
+2.5. Example
-------------
Here is a simple but complete example that sends client-ip address to a ip
diff --git a/include/types/spoe.h b/include/types/spoe.h
index 2d94e36..d360cba 100644
--- a/include/types/spoe.h
+++ b/include/types/spoe.h
@@ -164,31 +164,52 @@
};
/* Used during the config parsing only because, when a SPOE agent section is
- * parsed, messages can be undefined. */
-struct spoe_msg_placeholder {
- char *id; /* SPOE message placeholder id */
- struct list list; /* Use to chain SPOE message placeholders */
+ * parsed, messages/groups can be undefined. */
+struct spoe_placeholder {
+ char *id; /* SPOE placeholder id */
+ struct list list; /* Use to chain SPOE placeholders */
};
/* Describe a message that will be sent in a NOTIFY frame. A message has a name,
* an argument list (see above) and it is linked to a specific event. */
struct spoe_message {
- char *id; /* SPOE message id */
- unsigned int id_len; /* The message id length */
- struct spoe_agent *agent; /* SPOE agent owning this SPOE message */
+ char *id; /* SPOE message id */
+ unsigned int id_len; /* The message id length */
+ struct spoe_agent *agent; /* SPOE agent owning this SPOE message */
+ struct spoe_group *group; /* SPOE group owning this SPOE message (can be NULL) */
struct {
- char *file; /* file where the SPOE message appears */
- int line; /* line where the SPOE message appears */
+ char *file; /* file where the SPOE message appears */
+ int line; /* line where the SPOE message appears */
} conf; /* config information */
- unsigned int nargs; /* # of arguments */
- struct list args; /* Arguments added when the SPOE messages is sent */
- struct list list; /* Used to chain SPOE messages */
+ unsigned int nargs; /* # of arguments */
+ struct list args; /* Arguments added when the SPOE messages is sent */
+ struct list list; /* Used to chain SPOE messages */
+ struct list by_evt; /* By event list */
+ struct list by_grp; /* By group list */
- struct list acls; /* ACL declared on this message */
- struct acl_cond *cond; /* acl condition to meet */
- enum spoe_event event; /* SPOE_EV_* */
+ struct list acls; /* ACL declared on this message */
+ struct acl_cond *cond; /* acl condition to meet */
+ enum spoe_event event; /* SPOE_EV_* */
};
+/* Describe a group of messages that will be sent in a NOTIFY frame. A group has
+ * a name and a list of messages. It can be used by HAProxy, outside events
+ * processing, mainly in (tcp|http) rules. */
+struct spoe_group {
+ char *id; /* SPOE group id */
+ struct spoe_agent *agent; /* SPOE agent owning this SPOE group */
+ struct {
+ char *file; /* file where the SPOE group appears */
+ int line; /* line where the SPOE group appears */
+ } conf; /* config information */
+
+ struct list phs; /* List of placeholders used during conf parsing */
+ struct list messages; /* List of SPOE messages that will be sent by this
+ * group */
+
+ struct list list; /* Used to chain SPOE groups */
+};
+
/* Describe a SPOE agent. */
struct spoe_agent {
char *id; /* SPOE agent id (name) */
@@ -217,9 +238,13 @@
unsigned int min_applets; /* Minimum # applets alive at a time */
unsigned int max_fpa; /* Maximum # of frames handled per applet at once */
- struct list messages[SPOE_EV_EVENTS]; /* List of SPOE messages that will be sent
+ struct list events[SPOE_EV_EVENTS]; /* List of SPOE messages that will be sent
* for each supported events */
+ struct list groups; /* List of available SPOE groups */
+
+ struct list messages; /* list of all messages attached to this SPOE agent */
+
/* running info */
unsigned int frame_size; /* current maximum frame size, only used to encode messages */
unsigned int applets_act; /* # of applets alive at a time */
@@ -250,7 +275,8 @@
struct filter *filter; /* The SPOE filter */
struct stream *strm; /* The stream that should be offloaded */
- struct list *messages; /* List of messages that will be sent during the stream processing */
+ struct list *events; /* List of messages that will be sent during the stream processing */
+
struct buffer *buffer; /* Buffer used to store a encoded messages */
struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
struct list list;
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
index 44e6724..8494caf 100644
--- a/src/flt_spoe.c
+++ b/src/flt_spoe.c
@@ -74,14 +74,16 @@
char *curengine = NULL;
/* SPOE agent used during the parsing */
-struct spoe_agent *curagent = NULL;
-
-/* SPOE message used during the parsing */
-struct spoe_message *curmsg = NULL;
+/* SPOE agent/group/message used during the parsing */
+struct spoe_agent *curagent = NULL;
+struct spoe_group *curgrp = NULL;
+struct spoe_message *curmsg = NULL;
/* list of SPOE messages and placeholders used during the parsing */
struct list curmsgs;
-struct list curmps;
+struct list curgrps;
+struct list curmphs;
+struct list curgphs;
/* Pools used to allocate SPOE structs */
static struct pool_head *pool2_spoe_ctx = NULL;
@@ -97,12 +99,12 @@
* helper functions/globals
********************************************************************/
static void
-spoe_release_msg_placeholder(struct spoe_msg_placeholder *mp)
+spoe_release_placeholder(struct spoe_placeholder *ph)
{
- if (!mp)
+ if (!ph)
return;
- free(mp->id);
- free(mp);
+ free(ph->id);
+ free(ph);
}
static void
@@ -134,10 +136,20 @@
}
static void
+spoe_release_group(struct spoe_group *grp)
+{
+ if (!grp)
+ return;
+ free(grp->id);
+ free(grp->conf.file);
+ free(grp);
+}
+
+static void
spoe_release_agent(struct spoe_agent *agent)
{
- struct spoe_message *msg, *back;
- int i;
+ struct spoe_message *msg, *msgback;
+ struct spoe_group *grp, *grpback;
if (!agent)
return;
@@ -146,11 +158,13 @@
free(agent->var_pfx);
free(agent->engine_id);
free(agent->var_on_error);
- for (i = 0; i < SPOE_EV_EVENTS; ++i) {
- list_for_each_entry_safe(msg, back, &agent->messages[i], list) {
- LIST_DEL(&msg->list);
- spoe_release_message(msg);
- }
+ list_for_each_entry_safe(msg, msgback, &agent->messages, list) {
+ LIST_DEL(&msg->list);
+ spoe_release_message(msg);
+ }
+ list_for_each_entry_safe(grp, grpback, &agent->groups, list) {
+ LIST_DEL(&grp->list);
+ spoe_release_group(grp);
}
free(agent);
}
@@ -2105,7 +2119,7 @@
}
/* Loop on messages */
- list_for_each_entry(msg, messages, list) {
+ list_for_each_entry(msg, messages, by_evt) {
ctx->frag_ctx.curmsg = msg;
ctx->frag_ctx.curarg = NULL;
ctx->frag_ctx.curoff = UINT_MAX;
@@ -2466,7 +2480,7 @@
dir = ((ev < SPOE_EV_ON_SERVER_SESS) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES);
- if (LIST_ISEMPTY(&(ctx->messages[ev])))
+ if (LIST_ISEMPTY(&(ctx->events[ev])))
goto out;
if (ctx->state == SPOE_CTX_ST_ERROR)
@@ -2511,7 +2525,7 @@
if (ctx->state == SPOE_CTX_ST_ENCODING_MSGS) {
if (!spoe_acquire_buffer(&ctx->buffer, &ctx->buffer_wait))
goto out;
- ret = spoe_encode_messages(s, ctx, &(ctx->messages[ev]), dir);
+ ret = spoe_encode_messages(s, ctx, &(ctx->events[ev]), dir);
if (ret < 0)
goto error;
if (!ret)
@@ -2640,7 +2654,7 @@
ctx->state = SPOE_CTX_ST_NONE;
ctx->status_code = SPOE_CTX_ERR_NONE;
ctx->flags = 0;
- ctx->messages = conf->agent->messages;
+ ctx->events = conf->agent->events;
ctx->buffer = &buf_empty;
LIST_INIT(&ctx->buffer_wait.list);
ctx->buffer_wait.target = ctx;
@@ -2834,22 +2848,22 @@
ctx->state = SPOE_CTX_ST_READY;
filter->ctx = ctx;
- if (!LIST_ISEMPTY(&ctx->messages[SPOE_EV_ON_TCP_REQ_FE]))
+ if (!LIST_ISEMPTY(&ctx->events[SPOE_EV_ON_TCP_REQ_FE]))
filter->pre_analyzers |= AN_REQ_INSPECT_FE;
- if (!LIST_ISEMPTY(&ctx->messages[SPOE_EV_ON_TCP_REQ_BE]))
+ if (!LIST_ISEMPTY(&ctx->events[SPOE_EV_ON_TCP_REQ_BE]))
filter->pre_analyzers |= AN_REQ_INSPECT_BE;
- if (!LIST_ISEMPTY(&ctx->messages[SPOE_EV_ON_TCP_RSP]))
+ if (!LIST_ISEMPTY(&ctx->events[SPOE_EV_ON_TCP_RSP]))
filter->pre_analyzers |= AN_RES_INSPECT;
- if (!LIST_ISEMPTY(&ctx->messages[SPOE_EV_ON_HTTP_REQ_FE]))
+ if (!LIST_ISEMPTY(&ctx->events[SPOE_EV_ON_HTTP_REQ_FE]))
filter->pre_analyzers |= AN_REQ_HTTP_PROCESS_FE;
- if (!LIST_ISEMPTY(&ctx->messages[SPOE_EV_ON_HTTP_REQ_BE]))
+ if (!LIST_ISEMPTY(&ctx->events[SPOE_EV_ON_HTTP_REQ_BE]))
filter->pre_analyzers |= AN_REQ_HTTP_PROCESS_BE;
- if (!LIST_ISEMPTY(&ctx->messages[SPOE_EV_ON_HTTP_RSP]))
+ if (!LIST_ISEMPTY(&ctx->events[SPOE_EV_ON_HTTP_RSP]))
filter->pre_analyzers |= AN_RES_HTTP_PROCESS_FE;
return 1;
@@ -3083,7 +3097,9 @@
curagent->max_fpa = 100;
for (i = 0; i < SPOE_EV_EVENTS; ++i)
- LIST_INIT(&curagent->messages[i]);
+ LIST_INIT(&curagent->events[i]);
+ LIST_INIT(&curagent->groups);
+ LIST_INIT(&curagent->messages);
curagent->frame_size = curagent->max_frame_size;
curagent->applets_act = 0;
@@ -3109,27 +3125,51 @@
else if (!strcmp(args[0], "messages")) {
int cur_arg = 1;
while (*args[cur_arg]) {
- struct spoe_msg_placeholder *mp = NULL;
+ struct spoe_placeholder *ph = NULL;
- list_for_each_entry(mp, &curmps, list) {
- if (!strcmp(mp->id, args[cur_arg])) {
- Alert("parsing [%s:%d]: spoe-message message '%s' already declared.\n",
+ list_for_each_entry(ph, &curmphs, list) {
+ if (!strcmp(ph->id, args[cur_arg])) {
+ Alert("parsing [%s:%d]: spoe-message '%s' already used.\n",
file, linenum, args[cur_arg]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
}
- if ((mp = calloc(1, sizeof(*mp))) == NULL) {
+ if ((ph = calloc(1, sizeof(*ph))) == NULL) {
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
- mp->id = strdup(args[cur_arg]);
- LIST_ADDQ(&curmps, &mp->list);
+ ph->id = strdup(args[cur_arg]);
+ LIST_ADDQ(&curmphs, &ph->list);
cur_arg++;
}
}
+ else if (!strcmp(args[0], "groups")) {
+ int cur_arg = 1;
+ while (*args[cur_arg]) {
+ struct spoe_placeholder *ph = NULL;
+
+ list_for_each_entry(ph, &curgphs, list) {
+ if (!strcmp(ph->id, args[cur_arg])) {
+ Alert("parsing [%s:%d]: spoe-group '%s' already used.\n",
+ file, linenum, args[cur_arg]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ }
+
+ if ((ph = calloc(1, sizeof(*ph))) == NULL) {
+ Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
+ ph->id = strdup(args[cur_arg]);
+ LIST_ADDQ(&curgphs, &ph->list);
+ cur_arg++;
+ }
+ }
else if (!strcmp(args[0], "timeout")) {
unsigned int *tv = NULL;
const char *res;
@@ -3323,6 +3363,94 @@
out:
return err_code;
}
+static int
+cfg_parse_spoe_group(const char *file, int linenum, char **args, int kwm)
+{
+ struct spoe_group *grp;
+ const char *err;
+ int err_code = 0;
+
+ if ((cfg_scope == NULL && curengine != NULL) ||
+ (cfg_scope != NULL && curengine == NULL) ||
+ (curengine != NULL && cfg_scope != NULL && strcmp(curengine, cfg_scope)))
+ goto out;
+
+ if (!strcmp(args[0], "spoe-group")) { /* new spoe-group section */
+ if (!*args[1]) {
+ Alert("parsing [%s:%d] : missing name for spoe-group section.\n",
+ file, linenum);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
+ if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
+ err_code |= ERR_ABORT;
+ goto out;
+ }
+
+ err = invalid_char(args[1]);
+ if (err) {
+ Alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
+ file, linenum, *err, args[0], args[1]);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
+
+ list_for_each_entry(grp, &curgrps, list) {
+ if (!strcmp(grp->id, args[1])) {
+ Alert("parsing [%s:%d]: spoe-group section '%s' has the same"
+ " name as another one declared at %s:%d.\n",
+ file, linenum, args[1], grp->conf.file, grp->conf.line);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ }
+
+ if ((curgrp = calloc(1, sizeof(*curgrp))) == NULL) {
+ Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
+
+ curgrp->id = strdup(args[1]);
+ curgrp->conf.file = strdup(file);
+ curgrp->conf.line = linenum;
+ LIST_INIT(&curgrp->phs);
+ LIST_INIT(&curgrp->messages);
+ LIST_ADDQ(&curgrps, &curgrp->list);
+ }
+ else if (!strcmp(args[0], "messages")) {
+ int cur_arg = 1;
+ while (*args[cur_arg]) {
+ struct spoe_placeholder *ph = NULL;
+
+ list_for_each_entry(ph, &curgrp->phs, list) {
+ if (!strcmp(ph->id, args[cur_arg])) {
+ Alert("parsing [%s:%d]: spoe-message '%s' already used.\n",
+ file, linenum, args[cur_arg]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ }
+
+ if ((ph = calloc(1, sizeof(*ph))) == NULL) {
+ Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
+ ph->id = strdup(args[cur_arg]);
+ LIST_ADDQ(&curgrp->phs, &ph->list);
+ cur_arg++;
+ }
+ }
+ else if (*args[0]) {
+ Alert("parsing [%s:%d] : unknown keyword '%s' in spoe-group section.\n",
+ file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ out:
+ return err_code;
+}
static int
cfg_parse_spoe_message(const char *file, int linenum, char **args, int kwm)
@@ -3382,6 +3510,8 @@
curmsg->nargs = 0;
LIST_INIT(&curmsg->args);
LIST_INIT(&curmsg->acls);
+ LIST_INIT(&curmsg->by_evt);
+ LIST_INIT(&curmsg->by_grp);
LIST_ADDQ(&curmsgs, &curmsg->list);
}
else if (!strcmp(args[0], "args")) {
@@ -3518,7 +3648,8 @@
struct list backup_sections;
struct spoe_config *conf;
struct spoe_message *msg, *msgback;
- struct spoe_msg_placeholder *mp, *mpback;
+ struct spoe_group *grp, *grpback;
+ struct spoe_placeholder *ph, *phback;
char *file = NULL, *engine = NULL;
int ret, pos = *cur_arg + 1;
@@ -3561,7 +3692,8 @@
/* backup sections and register SPOE sections */
LIST_INIT(&backup_sections);
cfg_backup_sections(&backup_sections);
- cfg_register_section("spoe-agent", cfg_parse_spoe_agent, NULL);
+ cfg_register_section("spoe-agent", cfg_parse_spoe_agent, NULL);
+ cfg_register_section("spoe-group", cfg_parse_spoe_group, NULL);
cfg_register_section("spoe-message", cfg_parse_spoe_message, NULL);
/* Parse SPOE filter configuration file */
@@ -3569,6 +3701,10 @@
curproxy = px;
curagent = NULL;
curmsg = NULL;
+ LIST_INIT(&curmsgs);
+ LIST_INIT(&curgrps);
+ LIST_INIT(&curmphs);
+ LIST_INIT(&curgphs);
ret = readcfgfile(file);
curproxy = NULL;
@@ -3622,18 +3758,20 @@
if (curagent->engine_id == NULL)
curagent->engine_id = generate_pseudo_uuid();
- if (LIST_ISEMPTY(&curmps)) {
- Warning("Proxy '%s': No message used by SPOE agent '%s' declared at %s:%d.\n",
+ if (LIST_ISEMPTY(&curmphs) && LIST_ISEMPTY(&curgphs)) {
+ Warning("Proxy '%s': No message/group used by SPOE agent '%s' declared at %s:%d.\n",
px->id, curagent->id, curagent->conf.file, curagent->conf.line);
goto finish;
}
- list_for_each_entry_safe(mp, mpback, &curmps, list) {
- list_for_each_entry_safe(msg, msgback, &curmsgs, list) {
+ /* Replace placeholders by the corresponding messages for the SPOE
+ * agent */
+ list_for_each_entry(ph, &curmphs, list) {
+ list_for_each_entry(msg, &curmsgs, list) {
struct spoe_arg *arg;
unsigned int where;
- if (!strcmp(msg->id, mp->id)) {
+ if (!strcmp(msg->id, ph->id)) {
if ((px->cap & (PR_CAP_FE|PR_CAP_BE)) == (PR_CAP_FE|PR_CAP_BE)) {
if (msg->event == SPOE_EV_ON_TCP_REQ_BE)
msg->event = SPOE_EV_ON_TCP_REQ_FE;
@@ -3645,12 +3783,12 @@
msg->event == SPOE_EV_ON_HTTP_REQ_FE)) {
Warning("Proxy '%s': frontend event used on a backend proxy at %s:%d.\n",
px->id, msg->conf.file, msg->conf.line);
- goto next;
+ goto next_mph;
}
if (msg->event == SPOE_EV_NONE) {
Warning("Proxy '%s': Ignore SPOE message without event at %s:%d.\n",
px->id, msg->conf.file, msg->conf.line);
- goto next;
+ goto next_mph;
}
where = 0;
@@ -3711,37 +3849,93 @@
px->id, msg->conf.file, msg->conf.line,
sample_ckp_names(arg->expr->fetch->use),
sample_ckp_names(where));
- goto next;
+ goto next_mph;
}
}
msg->agent = curagent;
- LIST_DEL(&msg->list);
- LIST_ADDQ(&curagent->messages[msg->event], &msg->list);
- goto next;
+ LIST_ADDQ(&curagent->events[msg->event], &msg->by_evt);
+ goto next_mph;
}
}
memprintf(err, "SPOE agent '%s' try to use undefined SPOE message '%s' at %s:%d",
- curagent->id, mp->id, curagent->conf.file, curagent->conf.line);
+ curagent->id, ph->id, curagent->conf.file, curagent->conf.line);
goto error;
- next:
+ next_mph:
continue;
}
+ /* Replace placeholders by the corresponding groups for the SPOE
+ * agent */
+ list_for_each_entry(ph, &curgphs, list) {
+ list_for_each_entry_safe(grp, grpback, &curgrps, list) {
+ if (!strcmp(grp->id, ph->id)) {
+ grp->agent = curagent;
+ LIST_DEL(&grp->list);
+ LIST_ADDQ(&curagent->groups, &grp->list);
+ goto next_aph;
+ }
+ }
+ memprintf(err, "SPOE agent '%s' try to use undefined SPOE group '%s' at %s:%d",
+ curagent->id, ph->id, curagent->conf.file, curagent->conf.line);
+ goto error;
+ next_aph:
+ continue;
+ }
+
+ /* Replace placeholders by the corresponding message for each SPOE
+ * group of the SPOE agent */
+ list_for_each_entry(grp, &curagent->groups, list) {
+ list_for_each_entry_safe(ph, phback, &grp->phs, list) {
+ list_for_each_entry(msg, &curmsgs, list) {
+ if (!strcmp(msg->id, ph->id)) {
+ if (msg->group != NULL) {
+ memprintf(err, "SPOE message '%s' already belongs to "
+ "the SPOE group '%s' declare at %s:%d",
+ msg->id, msg->group->id,
+ msg->group->conf.file,
+ msg->group->conf.line);
+ goto error;
+ }
+
+ /* Scope for arguments are not checked for now. We will check
+ * them only if a rule use the corresponding SPOE group. */
+ msg->agent = curagent;
+ msg->group = grp;
+ LIST_DEL(&ph->list);
+ LIST_ADDQ(&grp->messages, &msg->by_grp);
+ goto next_mph_grp;
+ }
+ }
+ memprintf(err, "SPOE group '%s' try to use undefined SPOE message '%s' at %s:%d",
+ grp->id, ph->id, curagent->conf.file, curagent->conf.line);
+ goto error;
+ next_mph_grp:
+ continue;
+ }
+ }
+
finish:
+ /* move curmsgs to the agent message list */
+ curmsgs.n->p = &curagent->messages;
+ curmsgs.p->n = &curagent->messages;
+ curagent->messages = curmsgs;
+ LIST_INIT(&curmsgs);
+
conf->id = strdup(engine ? engine : curagent->id);
conf->agent = curagent;
- list_for_each_entry_safe(mp, mpback, &curmps, list) {
- LIST_DEL(&mp->list);
- spoe_release_msg_placeholder(mp);
+ list_for_each_entry_safe(ph, phback, &curmphs, list) {
+ LIST_DEL(&ph->list);
+ spoe_release_placeholder(ph);
}
- list_for_each_entry_safe(msg, msgback, &curmsgs, list) {
- Warning("Proxy '%s': Ignore unused SPOE messages '%s' declared at %s:%d.\n",
- px->id, msg->id, msg->conf.file, msg->conf.line);
- LIST_DEL(&msg->list);
- spoe_release_message(msg);
+ list_for_each_entry_safe(ph, phback, &curgphs, list) {
+ LIST_DEL(&ph->list);
+ spoe_release_placeholder(ph);
}
-
+ list_for_each_entry_safe(grp, grpback, &curgrps, list) {
+ LIST_DEL(&grp->list);
+ spoe_release_group(grp);
+ }
*cur_arg = pos;
fconf->id = spoe_filter_id;
fconf->ops = &spoe_ops;
@@ -3750,9 +3944,17 @@
error:
spoe_release_agent(curagent);
- list_for_each_entry_safe(mp, mpback, &curmps, list) {
- LIST_DEL(&mp->list);
- spoe_release_msg_placeholder(mp);
+ list_for_each_entry_safe(ph, phback, &curmphs, list) {
+ LIST_DEL(&ph->list);
+ spoe_release_placeholder(ph);
+ }
+ list_for_each_entry_safe(ph, phback, &curgphs, list) {
+ LIST_DEL(&ph->list);
+ spoe_release_placeholder(ph);
+ }
+ list_for_each_entry_safe(grp, grpback, &curgrps, list) {
+ LIST_DEL(&grp->list);
+ spoe_release_group(grp);
}
list_for_each_entry_safe(msg, msgback, &curmsgs, list) {
LIST_DEL(&msg->list);
@@ -3775,8 +3977,6 @@
{
flt_register_keywords(&flt_kws);
- LIST_INIT(&curmsgs);
- LIST_INIT(&curmps);
pool2_spoe_ctx = create_pool("spoe_ctx", sizeof(struct spoe_context), MEM_F_SHARED);
pool2_spoe_appctx = create_pool("spoe_appctx", sizeof(struct spoe_appctx), MEM_F_SHARED);
}