}
}
+/*
+ * flt_list_start() and flt_list_next() can be used to iterate over the list of filters
+ * for a given <strm> and <chn> combination. It will automatically choose the proper
+ * list to iterate from depending on the context.
+ *
+ * flt_list_start() has to be called exactly once to get the first value from the list
+ * to get the following values, use flt_list_next() until NULL is returned.
+ *
+ * Example:
+ *
+ * struct filter *filter;
+ *
+ * for (filter = flt_list_start(stream, channel); filter;
+ * filter = flt_list_next(stream, channel, filter)) {
+ * ...
+ * }
+ */
+static inline struct filter *flt_list_start(struct stream *strm, struct channel *chn)
+{
+ struct filter *filter;
+
+ filter = LIST_NEXT(&strm_flt(strm)->filters, struct filter *, list);
+ if (&filter->list == &strm_flt(strm)->filters)
+ filter = NULL; /* empty list */
+
+ return filter;
+}
+
+static inline struct filter *flt_list_next(struct stream *strm, struct channel *chn,
+ struct filter *filter)
+{
+ filter = LIST_NEXT(&filter->list, struct filter *, list);
+ if (&filter->list == &strm_flt(strm)->filters)
+ filter = NULL; /* end of list */
+
+ return filter;
+}
+
/* This function must be called when a filter alter payload data. It updates
* offsets of all previous filters. Do not call this function when a filter
* change the size of payload data leads to an undefined behavior.
struct stream *s = chn_strm(chn);
struct filter *f;
- list_for_each_entry(f, &strm_flt(s)->filters, list) {
+ for (f = flt_list_start(s, chn); f;
+ f = flt_list_next(s, chn, f)) {
if (f == filter)
break;
FLT_OFF(f, chn) += len;
static int handle_analyzer_result(struct stream *s, struct channel *chn, unsigned int an_bit, int ret);
-/* - resume_filter_list_start() and resume_filter_list_next() must always be used together.
+/*
+ * The API below is similar to flt_list_start() and flt_list_next() except that it can be
+ * interrupted and resumed!
+ *
+ * - resume_filter_list_start() and resume_filter_list_next() must always be used together.
* The first one sets the first filter value and the second one allows to get the
* next one until NULL is returned
*
(strm)->waiting_entity.ptr = NULL;
}
}
- else {
- filter = LIST_NEXT(&strm_flt(strm)->filters, struct filter *, list);
- if (&filter->list == &strm_flt(strm)->filters)
- filter = NULL; /* empty list */
- }
+ else
+ filter = flt_list_start(strm, chn);
return filter;
}
static inline struct filter *resume_filter_list_next(struct stream *strm, struct channel *chn,
struct filter *filter)
{
- filter = LIST_NEXT(&filter->list, struct filter *, list);
- if (&filter->list == &strm_flt(strm)->filters)
- filter = NULL; /* end of list */
- return filter;
+ /* simply an alias to flt_list_next() */
+ return flt_list_next(strm, chn, filter);
}
static inline void resume_filter_list_break(struct stream *strm, struct channel *chn,
struct filter *filter;
DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg);
- list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+ for (filter = flt_list_start(s, msg->chn); filter;
+ filter = flt_list_next(s, msg->chn, filter)) {
if (FLT_OPS(filter)->http_reset) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = data = len - out;
DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg);
- list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+ for (filter = flt_list_start(s, msg->chn); filter;
+ filter = flt_list_next(s, msg->chn, filter)) {
unsigned long long *flt_off = &FLT_OFF(filter, msg->chn);
unsigned int offset = *flt_off - *strm_off;
DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_FLT_ANA, s);
- list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+ for (filter = flt_list_start(s, chn); filter;
+ filter = flt_list_next(s, chn, filter)) {
if (FLT_OPS(filter)->channel_post_analyze && (filter->post_analyzers & an_bit)) {
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
filter->calls++;
size_t data = http_get_hdrs_size(htxbuf(&chn->buf));
struct filter *f;
- list_for_each_entry(f, &strm_flt(s)->filters, list)
+ for (f = flt_list_start(s, chn); f;
+ f = flt_list_next(s, chn, f))
FLT_OFF(f, chn) = data;
}
ret = data = len - out;
DBG_TRACE_ENTER(STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
- list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+ for (filter = flt_list_start(s, chn); filter;
+ filter = flt_list_next(s, chn, filter)) {
unsigned long long *flt_off = &FLT_OFF(filter, chn);
unsigned int offset = *flt_off - *strm_off;