* number of errors encountered.
*
*
+ * - attach : Called after a filter instance creation, when it is
+ * attached to a stream. This happens when the stream
+ * is started for filters defined on the stream's
+ * frontend and when the backend is set for filters
+ * declared on the stream's backend.
+ * Returns a negative value if an error occurs, 0 if
+ * the filter must be ignored for the stream, any other
+ * value otherwise.
* - stream_start : Called when a stream is started. This callback will
- * only be called for filters defined on a proxy with
- * the frontend capability.
+ * only be called for filters defined on the stream's
+ * frontend.
+ * Returns a negative value if an error occurs, any
+ * other value otherwise.
+ * - stream_set_backend : Called when a backend is set for a stream. This
+ * callbacks will be called for all filters attached
+ * to a stream (frontend and backend).
* Returns a negative value if an error occurs, any
* other value otherwise.
* - stream_stop : Called when a stream is stopped. This callback will
- * only be called for filters defined on a proxy with
- * the frontend capability.
+ * only be called for filters defined on the stream's
+ * frontend.
+ * - detach : Called when a filter instance is detached from a
+ * stream, before its destruction. This happens when
+ * the stream is stopped for filters defined on the
+ * stream's frontend and when the analyze ends for
+ * filters defined on the stream's backend.
*
*
* - channel_start_analyze: Called when a filter starts to analyze a channel.
int (*init) (struct proxy *p, struct flt_conf *fconf);
void (*deinit)(struct proxy *p, struct flt_conf *fconf);
int (*check) (struct proxy *p, struct flt_conf *fconf);
-
/*
* Stream callbacks
*/
- int (*stream_start) (struct stream *s, struct filter *f);
- void (*stream_stop) (struct stream *s, struct filter *f);
+ int (*attach) (struct stream *s, struct filter *f);
+ int (*stream_start) (struct stream *s, struct filter *f);
+ int (*stream_set_backend)(struct stream *s, struct filter *f, struct proxy *be);
+ void (*stream_stop) (struct stream *s, struct filter *f);
+ void (*detach) (struct stream *s, struct filter *f);
/*
* Channel callbacks
flt_stream_add_filter(struct stream *s, struct flt_conf *fconf, unsigned int flags)
{
struct filter *f = pool_alloc2(pool2_filter);
+
if (!f) /* not enough memory */
return -1;
memset(f, 0, sizeof(*f));
f->config = fconf;
f->flags |= flags;
+
+ if (FLT_OPS(f)->attach) {
+ int ret = FLT_OPS(f)->attach(s, f);
+ if (ret <= 0) {
+ pool_free2(pool2_filter, f);
+ return ret;
+ }
+ }
+
LIST_ADDQ(&strm_flt(s)->filters, &f->list);
strm_flt(s)->flags |= STRM_FLT_FL_HAS_FILTERS;
return 0;
list_for_each_entry_safe(filter, back, &strm_flt(s)->filters, list) {
if (!only_backend || (filter->flags & FLT_FL_IS_BACKEND_FILTER)) {
+ if (FLT_OPS(filter)->detach)
+ FLT_OPS(filter)->detach(s, filter);
LIST_DEL(&filter->list);
pool_free2(pool2_filter, filter);
}
/*
* Called when a backend is set for a stream. If the frontend and the backend
- * are the same, this function does nothing. Else it attaches all backend
- * filters to the stream. Returns -1 if an error occurs, 0 otherwise.
+ * are not the same, this function attaches all backend filters to the
+ * stream. Returns -1 if an error occurs, 0 otherwise.
*/
int
flt_set_stream_backend(struct stream *s, struct proxy *be)
{
struct flt_conf *fconf;
+ struct filter *filter;
if (strm_fe(s) == be)
- return 0;
+ goto end;
list_for_each_entry(fconf, &be->filter_configs, list) {
if (flt_stream_add_filter(s, fconf, FLT_FL_IS_BACKEND_FILTER) < 0)
return -1;
}
+
+ end:
+ list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+ if (FLT_OPS(filter)->stream_set_backend &&
+ FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
+ return -1;
+ }
+
return 0;
}
return (s->flags & SF_BE_ASSIGNED) ? "backend" : "frontend";
}
+static const char *
+filter_type(const struct filter *f)
+{
+ return (f->flags & FLT_FL_IS_BACKEND_FILTER) ? "backend" : "frontend";
+}
+
/***************************************************************************
* Hooks that manage the filter lifecycle (init/check/deinit)
**************************************************************************/
/**************************************************************************
* Hooks to handle start/stop of streams
*************************************************************************/
+/* Called when a filter instance is created and attach to a stream */
+static int
+trace_attach(struct stream *s, struct filter *filter)
+{
+ struct trace_config *conf = FLT_CONF(filter);
+
+ STRM_TRACE(conf, s, "%-25s: filter-type=%s",
+ __FUNCTION__, filter_type(filter));
+ return 1;
+}
+
+/* Called when a filter instance is detach from a stream, just before its
+ * destruction */
+static void
+trace_detach(struct stream *s, struct filter *filter)
+{
+ struct trace_config *conf = FLT_CONF(filter);
+
+ STRM_TRACE(conf, s, "%-25s: filter-type=%s",
+ __FUNCTION__, filter_type(filter));
+}
+
/* Called when a stream is created */
static int
trace_stream_start(struct stream *s, struct filter *filter)
return 0;
}
+
+/* Called when a backend is set for a stream */
+static int
+trace_stream_set_backend(struct stream *s, struct filter *filter,
+ struct proxy *be)
+{
+ struct trace_config *conf = FLT_CONF(filter);
+
+ STRM_TRACE(conf, s, "%-25s: backend=%s",
+ __FUNCTION__, be->id);
+ return 0;
+}
+
/* Called when a stream is destroyed */
static void
trace_stream_stop(struct stream *s, struct filter *filter)
.check = trace_check,
/* Handle start/stop of streams */
- .stream_start = trace_stream_start,
- .stream_stop = trace_stream_stop,
+ .attach = trace_attach,
+ .detach = trace_detach,
+ .stream_start = trace_stream_start,
+ .stream_set_backend = trace_stream_set_backend,
+ .stream_stop = trace_stream_stop,
/* Handle channels activity */
.channel_start_analyze = trace_chn_start_analyze,