From: Christopher Faulet Date: Tue, 24 Nov 2015 15:24:13 +0000 (+0100) Subject: MEDIUM: filters: Use macros to call filters callbacks to speed-up processing X-Git-Tag: v1.7-dev2~119 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e34429515912c34d6f63e8b58bb5cb5bf3096fe;p=thirdparty%2Fhaproxy.git MEDIUM: filters: Use macros to call filters callbacks to speed-up processing When no filter is attached to the stream, the CPU footprint due to the calls to filters_* functions is huge, especially for chunk-encoded messages. Using macros to check if we have some filters or not is a great improvement. Furthermore, instead of checking the filter list emptiness, we introduce a flag to know if filters are attached or not to a stream. --- diff --git a/include/proto/filters.h b/include/proto/filters.h index 2e21577846..0e0eb5f304 100644 --- a/include/proto/filters.h +++ b/include/proto/filters.h @@ -35,6 +35,50 @@ #define FLT_NXT(flt, chn) ((flt)->next[CHN_IDX(chn)]) #define FLT_FWD(flt, chn) ((flt)->fwd[CHN_IDX(chn)]) +#define HAS_FILTERS(strm) ((strm)->strm_flt.has_filters) + +#define FLT_STRM_CB_IMPL_0(strm, call) \ + do { \ + if (HAS_FILTERS(strm)) { call; } \ + } while (0) +#define FLT_STRM_CB_IMPL_1(strm, call, default_ret, ...) \ + (HAS_FILTERS(strm) ? call : default_ret) +#define FLT_STRM_CB_IMPL_2(strm, call, default_ret, on_error) \ + ({ \ + int _ret; \ + if (HAS_FILTERS(strm)) { \ + _ret = call; \ + if (_ret < 0) { on_error; } \ + } \ + else \ + _ret = default_ret; \ + _ret; \ + }) +#define FLT_STRM_CB_IMPL_3(strm, call, default_ret, on_error, on_wait) \ + ({ \ + int _ret; \ + if (HAS_FILTERS(strm)) { \ + _ret = call; \ + if (_ret < 0) { on_error; } \ + if (!_ret) { on_wait; } \ + } \ + else \ + _ret = default_ret; \ + _ret; \ + }) + +#define FLT_STRM_CB_IMPL_X(strm, call, A, B, C, CB_IMPL, ...) CB_IMPL + +#define FLT_STRM_CB(strm, call, ...) \ + FLT_STRM_CB_IMPL_X(strm, call, ##__VA_ARGS__, \ + FLT_STRM_CB_IMPL_3(strm, call, ##__VA_ARGS__), \ + FLT_STRM_CB_IMPL_2(strm, call, ##__VA_ARGS__), \ + FLT_STRM_CB_IMPL_1(strm, call, ##__VA_ARGS__), \ + FLT_STRM_CB_IMPL_0(strm, call)) + +#define CALL_FILTER_ANALYZER(analyzer, strm, chn, bit) \ + if (!HAS_FILTERS(strm) || analyzer((strm), (chn), bit)) ; else break + extern struct pool_head *pool2_filter; int flt_init(struct proxy *p); diff --git a/include/types/stream.h b/include/types/stream.h index d6e05e4f74..e2efc930bc 100644 --- a/include/types/stream.h +++ b/include/types/stream.h @@ -128,6 +128,7 @@ struct stream { struct { struct list filters; struct filter *current[2]; /* 0: request, 1: response */ + char has_filters; } strm_flt; struct task *task; /* the task associated with this stream */ diff --git a/src/filters.c b/src/filters.c index 974c742f49..01dc5fa8e8 100644 --- a/src/filters.c +++ b/src/filters.c @@ -295,6 +295,7 @@ flt_stream_add_filter(struct stream *s, struct filter *filter, f->conf = filter->conf; f->is_backend_filter = is_backend; LIST_ADDQ(&s->strm_flt.filters, &f->list); + s->strm_flt.has_filters = 1; return 0; } @@ -309,6 +310,7 @@ flt_stream_init(struct stream *s) LIST_INIT(&s->strm_flt.filters); memset(s->strm_flt.current, 0, sizeof(s->strm_flt.current)); + s->strm_flt.has_filters = 0; list_for_each_entry(filter, &strm_fe(s)->filters, list) { if (flt_stream_add_filter(s, filter, 0) < 0) return -1; @@ -333,6 +335,8 @@ flt_stream_release(struct stream *s, int only_backend) pool_free2(pool2_filter, filter); } } + if (LIST_ISEMPTY(&s->strm_flt.filters)) + s->strm_flt.has_filters = 0; } /* @@ -393,9 +397,6 @@ flt_http_headers(struct stream *s, struct http_msg *msg) struct filter *filter; int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, msg->chn) { if (filter->ops && filter->ops->http_headers) { ret = filter->ops->http_headers(s, filter, msg); @@ -419,9 +420,6 @@ flt_http_start_chunk(struct stream *s, struct http_msg *msg) { int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, msg->chn) { if (filter->ops->http_start_chunk) { ret = filter->ops->http_start_chunk(s, filter, msg); @@ -450,12 +448,6 @@ flt_http_data(struct stream *s, struct http_msg *msg) unsigned int buf_i; int ret = 0; - /* No filter, consume all available data */ - if (LIST_ISEMPTY(&s->strm_flt.filters)) { - ret = MIN(msg->chunk_len, msg->chn->buf->i - msg->next); - goto end; - } - /* Save buffer state */ buf_i = msg->chn->buf->i; list_for_each_entry(filter, &s->strm_flt.filters, list) { @@ -483,7 +475,6 @@ flt_http_data(struct stream *s, struct http_msg *msg) } /* Restore the original buffer state */ msg->chn->buf->i = buf_i; - end: return ret; } @@ -492,9 +483,6 @@ flt_http_end_chunk(struct stream *s, struct http_msg *msg) { int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, msg->chn) { if (filter->ops->http_end_chunk) { ret = filter->ops->http_end_chunk(s, filter, msg); @@ -513,9 +501,6 @@ flt_http_last_chunk(struct stream *s, struct http_msg *msg) { int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, msg->chn) { if (filter->ops->http_last_chunk) { ret = filter->ops->http_last_chunk(s, filter, msg); @@ -543,9 +528,6 @@ flt_http_chunk_trailers(struct stream *s, struct http_msg *msg) { int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, msg->chn) { if (filter->ops->http_chunk_trailers) { ret = filter->ops->http_chunk_trailers(s, filter, msg); @@ -570,9 +552,6 @@ flt_http_end(struct stream *s, struct http_msg *msg) { int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, msg->chn) { if (filter->ops->http_end) { ret = filter->ops->http_end(s, filter, msg); @@ -594,9 +573,6 @@ flt_http_reset(struct stream *s, struct http_msg *msg) { struct filter *filter; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - return; - list_for_each_entry(filter, &s->strm_flt.filters, list) { if (filter->ops->http_reset) filter->ops->http_reset(s, filter, msg); @@ -612,9 +588,6 @@ flt_http_reply(struct stream *s, short status, const struct chunk *msg) { struct filter *filter; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - return; - list_for_each_entry(filter, &s->strm_flt.filters, list) { if (filter->ops->http_reply) filter->ops->http_reply(s, filter, status, msg); @@ -636,10 +609,6 @@ flt_http_forward_data(struct stream *s, struct http_msg *msg, unsigned int len) struct filter *filter = NULL; int ret = len; - /* No filter, forward all data */ - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - list_for_each_entry(filter, &s->strm_flt.filters, list) { if (filter->ops->http_forward_data) { /* Remove bytes that the current filter considered as @@ -719,9 +688,6 @@ flt_analyze(struct stream *s, struct channel *chn, unsigned int an_bit) { int ret = 1; - if (LIST_ISEMPTY(&s->strm_flt.filters)) - goto end; - RESUME_FILTER_LOOP(s, chn) { if (filter->ops->channel_analyze) { ret = filter->ops->channel_analyze(s, filter, chn, an_bit); @@ -732,7 +698,6 @@ flt_analyze(struct stream *s, struct channel *chn, unsigned int an_bit) check_result: ret = handle_analyzer_result(s, chn, 0, ret); - end: return ret; } diff --git a/src/proto_http.c b/src/proto_http.c index 48d12f0f6e..3b39e9cefa 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -935,7 +935,7 @@ int http_remove_header2(struct http_msg *msg, struct hdr_idx *idx, struct hdr_ct static void http_server_error(struct stream *s, struct stream_interface *si, int err, int finst, int status, const struct chunk *msg) { - flt_http_reply(s, status, msg); + FLT_STRM_CB(s, flt_http_reply(s, status, msg)); channel_auto_read(si_oc(si)); channel_abort(si_oc(si)); channel_auto_close(si_oc(si)); @@ -970,7 +970,7 @@ void http_reply_and_close(struct stream *s, short status, struct chunk *msg) { s->txn->flags &= ~TX_WAIT_NEXT_RQ; - flt_http_reply(s, status, msg); + FLT_STRM_CB(s, flt_http_reply(s, status, msg)); stream_int_retnclose(&s->si[0], msg); } @@ -4027,7 +4027,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s } memcpy(trash.str + trash.len, "\r\n\r\n", 4); trash.len += 4; - flt_http_reply(s, txn->status, &trash); + FLT_STRM_CB(s, flt_http_reply(s, txn->status, &trash)); bo_inject(res->chn, trash.str, trash.len); /* "eat" the request */ bi_fast_delete(req->chn->buf, req->sov); @@ -5071,14 +5071,14 @@ void http_end_txn_clean_session(struct stream *s) si_idle_conn(&s->si[1], &srv->idle_conns); } - if (LIST_ISEMPTY(&s->strm_flt.filters)) { - s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0; - s->res.analysers = 0; - } - else { + if (HAS_FILTERS(s)) { s->req.analysers &= AN_FLT_END; s->res.analysers &= AN_FLT_END; } + else { + s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0; + s->res.analysers = 0; + } } @@ -5442,7 +5442,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) struct session *sess = s->sess; struct http_txn *txn = s->txn; struct http_msg *msg = &s->txn->req; - int ret, ret2; + int ret; if (unlikely(msg->msg_state < HTTP_MSG_BODY)) return 0; @@ -5462,25 +5462,16 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) * decide whether to return 100, 417 or anything else in return of * an "Expect: 100-continue" header. */ - if (msg->msg_state == HTTP_MSG_BODY) { /* we have msg->sov which points to the first byte of message * body, and req->buf.p still points to the beginning of the * message. We forward the headers now, as we don't need them * anymore, and we want to flush them. */ - ret = flt_http_headers(s, msg); - if (ret < 0) - goto return_bad_req; - if (!ret) - return 0; - - ret = flt_http_forward_data(s, msg, msg->sov); - if (ret < 0) - goto return_bad_req; - b_adv(req->buf, ret); - msg->next -= ret; - msg->sov -= ret; + FLT_STRM_CB(s, flt_http_headers(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_req, + /* on_wait */ return 0); /* The previous analysers guarantee that the state is somewhere * between MSG_BODY and the first MSG_DATA. So msg->sol and @@ -5526,10 +5517,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) if (msg->msg_state == HTTP_MSG_DATA) { /* must still forward */ /* we may have some pending data starting at req->buf->p */ - ret = flt_http_data(s, msg); - if (ret < 0) - goto aborted_xfer; - msg->next += ret; + ret = FLT_STRM_CB(s, flt_http_data(s, msg), + /* default_ret */ MIN(msg->chunk_len, req->buf->i - msg->next), + /* on_error */ goto aborted_xfer); + msg->next += ret; msg->chunk_len -= ret; if (msg->chunk_len) { @@ -5561,13 +5552,16 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) goto return_bad_req; } } - ret = (msg->chunk_len - ? flt_http_start_chunk(s, msg) - : flt_http_last_chunk(s, msg)); - if (ret < 0) - goto return_bad_req; - if (!ret) - goto missing_data; + if (msg->chunk_len) + FLT_STRM_CB(s, flt_http_start_chunk(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_req, + /* on_wait */ goto missing_data); + else + FLT_STRM_CB(s, flt_http_last_chunk(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_req, + /* on_wait */ goto missing_data); msg->next += msg->sol; msg->sol = 0; msg->msg_state = msg->chunk_len ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS; @@ -5586,11 +5580,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) goto return_bad_req; } } - ret = flt_http_end_chunk(s, msg); - if (ret < 0) - goto return_bad_req; - if (!ret) - goto missing_data; + FLT_STRM_CB(s, flt_http_end_chunk(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_req, + /* on_wait */ goto missing_data); msg->next += msg->sol; msg->sol = 0; msg->msg_state = HTTP_MSG_CHUNK_SIZE; @@ -5607,11 +5600,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) goto return_bad_req; } } - ret2 = flt_http_chunk_trailers(s, msg); - if (ret2 < 0) - goto return_bad_req; - if (!ret2) - goto missing_data; + FLT_STRM_CB(s, flt_http_chunk_trailers(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_req, + /* on_wait */ goto missing_data); msg->next += msg->sol; msg->sol = 0; if (!ret) @@ -5627,22 +5619,20 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) /* we may have some pending data starting at req->buf->p * such as last chunk of data or trailers. */ - ret = flt_http_forward_data(s, msg, msg->next); - if (ret < 0) - goto return_bad_req; + ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next), + /* default_ret */ msg->next, + /* on_error */ goto return_bad_req); b_adv(req->buf, ret); msg->next -= ret; if (unlikely(!(s->req.flags & CF_WROTE_DATA) || msg->sov > 0)) msg->sov -= ret; - if (msg->next) goto skip_resync_states; - ret = flt_http_end(s, msg); - if (ret < 0) - goto return_bad_req; - if (!ret) - goto skip_resync_states; + FLT_STRM_CB(s, flt_http_end(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_req, + /* on_wait */ goto skip_resync_states); msg->msg_state = HTTP_MSG_DONE; } else { @@ -5703,14 +5693,14 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) missing_data: /* we may have some pending data starting at req->buf->p */ - ret = flt_http_forward_data(s, msg, msg->next); - if (ret < 0) - goto return_bad_req; + ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next), + /* default_ret */ msg->next, + /* on_error */ goto return_bad_req); b_adv(req->buf, ret); msg->next -= ret; if (unlikely(!(s->req.flags & CF_WROTE_DATA) || msg->sov > 0)) msg->sov -= ret; - if (LIST_ISEMPTY(&s->strm_flt.filters)) + if (!HAS_FILTERS(s)) msg->chunk_len -= channel_forward(req, msg->chunk_len); /* stop waiting for data if the input is closed before the end */ @@ -6162,7 +6152,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) msg->msg_state = HTTP_MSG_RPBEFORE; txn->status = 0; s->logs.t_data = -1; /* was not a response yet */ - flt_http_reset(s, msg); + FLT_STRM_CB(s, flt_http_reset(s, msg)); goto next_one; case 200: @@ -6733,8 +6723,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s } skip_header_mangling: - if ((msg->flags & HTTP_MSGF_XFER_LEN) || - !LIST_ISEMPTY(&s->strm_flt.filters) || + if ((msg->flags & HTTP_MSGF_XFER_LEN) || HAS_FILTERS(s) || (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN) { rep->analysers &= ~AN_FLT_XFER_DATA; rep->analysers |= AN_RES_HTTP_XFER_BODY; @@ -6782,12 +6771,13 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s * is performed at once on final states for all bytes parsed, or when leaving * on missing data. */ + int http_response_forward_body(struct stream *s, struct channel *res, int an_bit) { struct session *sess = s->sess; struct http_txn *txn = s->txn; struct http_msg *msg = &s->txn->rsp; - int ret, ret2; + int ret; if (unlikely(msg->msg_state < HTTP_MSG_BODY)) return 0; @@ -6812,18 +6802,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit * message. We forward the headers now, as we don't need them * anymore, and we want to flush them. */ - ret = flt_http_headers(s, msg); - if (ret < 0) - goto return_bad_res; - if (!ret) - return 0; - - ret = flt_http_forward_data(s, msg, msg->sov); - if (ret < 0) - goto return_bad_res; - b_adv(res->buf, ret); - msg->next -= ret; - msg->sov -= ret; + FLT_STRM_CB(s, flt_http_headers(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_res, + /* on_wait */ return 0); /* The previous analysers guarantee that the state is somewhere * between MSG_BODY and the first MSG_DATA. So msg->sol and @@ -6852,11 +6834,14 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit * found, so we must read the body until the server * connection is closed. In that case, we eat data as * they come. */ - if (!(msg->flags & HTTP_MSGF_XFER_LEN)) - msg->chunk_len = (res->buf->i - msg->next); - ret = flt_http_data(s, msg); - if (ret < 0) - goto aborted_xfer; + if (!(msg->flags & HTTP_MSGF_XFER_LEN)) { + unsigned long long len = (res->buf->i - msg->next); + msg->chunk_len += len; + msg->body_len += len; + } + ret = FLT_STRM_CB(s, flt_http_data(s, msg), + /* default_ret */ MIN(msg->chunk_len, res->buf->i - msg->next), + /* on_error */ goto aborted_xfer); msg->next += ret; msg->chunk_len -= ret; if (msg->chunk_len) { @@ -6891,11 +6876,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit goto return_bad_res; } } - ret = flt_http_end_chunk(s, msg); - if (ret < 0) - goto return_bad_res; - if (!ret) - goto missing_data; + FLT_STRM_CB(s, flt_http_end_chunk(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_res, + /* on_wait */ goto missing_data); msg->next += msg->sol; msg->sol = 0; msg->msg_state = HTTP_MSG_CHUNK_SIZE; @@ -6916,13 +6900,16 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit goto return_bad_res; } } - ret = (msg->chunk_len - ? flt_http_start_chunk(s, msg) - : flt_http_last_chunk(s, msg)); - if (ret < 0) - goto return_bad_res; - if (!ret) - goto missing_data; + if (msg->chunk_len) + FLT_STRM_CB(s, flt_http_start_chunk(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_res, + /* on_wait */ goto missing_data); + else + FLT_STRM_CB(s, flt_http_last_chunk(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_res, + /* on_wait */ goto missing_data); msg->next += msg->sol; msg->sol = 0; msg->msg_state = msg->chunk_len ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS; @@ -6939,11 +6926,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit goto return_bad_res; } } - ret2 = flt_http_chunk_trailers(s, msg); - if (ret2 < 0) - goto return_bad_res; - if (!ret2) - goto missing_data; + FLT_STRM_CB(s, flt_http_chunk_trailers(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_res, + /* on_wait */ goto missing_data); msg->next += msg->sol; msg->sol = 0; if (!ret) @@ -6960,22 +6946,20 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit /* we may have some pending data starting at res->buf->p * such as a last chunk of data or trailers. */ - ret = flt_http_forward_data(s, msg, msg->next); - if (ret < 0) - goto return_bad_res; + ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next), + /* default_ret */ msg->next, + /* on_error */ goto return_bad_res); b_adv(res->buf, ret); msg->next -= ret; if (msg->sov > 0) msg->sov -= ret; - if (msg->next) goto skip_resync_states; - ret = flt_http_end(s, msg); - if (ret < 0) - goto return_bad_res; - if (!ret) - goto skip_resync_states; + FLT_STRM_CB(s, flt_http_end(s, msg), + /* default_ret */ 1, + /* on_error */ goto return_bad_res, + /* on_wait */ goto skip_resync_states); msg->msg_state = HTTP_MSG_DONE; /* fall through */ @@ -7013,15 +6997,14 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit missing_data: /* we may have some pending data starting at res->buf->p */ - ret = flt_http_forward_data(s, msg, msg->next); - if (ret < 0) - goto return_bad_res; + ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next), + /* default_ret */ msg->next, + /* on_error */ goto return_bad_res); b_adv(res->buf, ret); msg->next -= ret; if (msg->sov > 0) msg->sov -= ret; - - if (LIST_ISEMPTY(&s->strm_flt.filters)) + if (!HAS_FILTERS(s)) msg->chunk_len -= channel_forward(res, msg->chunk_len); if (res->flags & CF_SHUTW) diff --git a/src/stream.c b/src/stream.c index c5d6d437b1..a274ea450d 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1765,107 +1765,95 @@ struct task *process_stream(struct task *t) } if (ana_list & AN_REQ_INSPECT_FE) { - if (!flt_analyze(s, req, AN_REQ_INSPECT_FE)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_INSPECT_FE); if (!tcp_inspect_request(s, req, AN_REQ_INSPECT_FE)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_INSPECT_FE); } if (ana_list & AN_REQ_WAIT_HTTP) { - if (!flt_analyze(s, req, AN_REQ_WAIT_HTTP)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_WAIT_HTTP); if (!http_wait_for_request(s, req, AN_REQ_WAIT_HTTP)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_WAIT_HTTP); } if (ana_list & AN_REQ_HTTP_BODY) { - if (!flt_analyze(s, req, AN_REQ_HTTP_BODY)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_BODY); if (!http_wait_for_request_body(s, req, AN_REQ_HTTP_BODY)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_BODY); } if (ana_list & AN_REQ_HTTP_PROCESS_FE) { - if (!flt_analyze(s, req, AN_REQ_HTTP_PROCESS_FE)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_PROCESS_FE); if (!http_process_req_common(s, req, AN_REQ_HTTP_PROCESS_FE, sess->fe)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_FE); } if (ana_list & AN_REQ_SWITCHING_RULES) { - if (!flt_analyze(s, req, AN_REQ_SWITCHING_RULES)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_SWITCHING_RULES); if (!process_switching_rules(s, req, AN_REQ_SWITCHING_RULES)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_SWITCHING_RULES); } - if (ana_list & AN_REQ_INSPECT_BE) { - if (!flt_analyze(s, req, AN_REQ_INSPECT_BE)) + if (ana_list & AN_FLT_START_BE) { + if (!flt_start_analyze(s, req, AN_FLT_START_BE)) break; + UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_FLT_START_BE); + } + + if (ana_list & AN_REQ_INSPECT_BE) { + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_INSPECT_BE); if (!tcp_inspect_request(s, req, AN_REQ_INSPECT_BE)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_INSPECT_BE); } if (ana_list & AN_REQ_HTTP_PROCESS_BE) { - if (!flt_analyze(s, req, AN_REQ_HTTP_PROCESS_BE)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_PROCESS_BE); if (!http_process_req_common(s, req, AN_REQ_HTTP_PROCESS_BE, s->be)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_BE); } if (ana_list & AN_REQ_HTTP_TARPIT) { - if (!flt_analyze(s, req, AN_REQ_HTTP_TARPIT)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_TARPIT); if (!http_process_tarpit(s, req, AN_REQ_HTTP_TARPIT)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_TARPIT); } if (ana_list & AN_REQ_SRV_RULES) { - if (!flt_analyze(s, req, AN_REQ_SRV_RULES)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_SRV_RULES); if (!process_server_rules(s, req, AN_REQ_SRV_RULES)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_SRV_RULES); } if (ana_list & AN_REQ_HTTP_INNER) { - if (!flt_analyze(s, req, AN_REQ_HTTP_INNER)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_INNER); if (!http_process_request(s, req, AN_REQ_HTTP_INNER)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_INNER); } if (ana_list & AN_REQ_PRST_RDP_COOKIE) { - if (!flt_analyze(s, req, AN_REQ_PRST_RDP_COOKIE)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_PRST_RDP_COOKIE); if (!tcp_persist_rdp_cookie(s, req, AN_REQ_PRST_RDP_COOKIE)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_PRST_RDP_COOKIE); } if (ana_list & AN_REQ_STICKING_RULES) { - if (!flt_analyze(s, req, AN_REQ_STICKING_RULES)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_STICKING_RULES); if (!process_sticking_rules(s, req, AN_REQ_STICKING_RULES)) break; UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_STICKING_RULES); } - if (ana_list & AN_FLT_START_BE) { - if (!flt_start_analyze(s, req, AN_FLT_START_BE)) - break; - UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_FLT_START_BE); - } - if (ana_list & AN_FLT_XFER_DATA) { if (!flt_xfer_data(s, req, AN_FLT_XFER_DATA)) break; @@ -1958,44 +1946,40 @@ struct task *process_stream(struct task *t) UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_FLT_START_FE); } - if (ana_list & AN_RES_INSPECT) { - if (!flt_analyze(s, res, AN_RES_INSPECT)) + if (ana_list & AN_FLT_START_BE) { + if (!flt_start_analyze(s, res, AN_FLT_START_BE)) break; + UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_FLT_START_BE); + } + + if (ana_list & AN_RES_INSPECT) { + CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_INSPECT); if (!tcp_inspect_response(s, res, AN_RES_INSPECT)) break; UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_INSPECT); } if (ana_list & AN_RES_WAIT_HTTP) { - if (!flt_analyze(s, res, AN_RES_WAIT_HTTP)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_WAIT_HTTP); if (!http_wait_for_response(s, res, AN_RES_WAIT_HTTP)) break; UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_WAIT_HTTP); } if (ana_list & AN_RES_STORE_RULES) { - if (!flt_analyze(s, res, AN_RES_STORE_RULES)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_STORE_RULES); if (!process_store_rules(s, res, AN_RES_STORE_RULES)) break; UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_STORE_RULES); } if (ana_list & AN_RES_HTTP_PROCESS_BE) { - if (!flt_analyze(s, res, AN_RES_HTTP_PROCESS_BE)) - break; + CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_HTTP_PROCESS_BE); if (!http_process_res_common(s, res, AN_RES_HTTP_PROCESS_BE, s->be)) break; UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_HTTP_PROCESS_BE); } - if (ana_list & AN_FLT_START_BE) { - if (!flt_start_analyze(s, res, AN_FLT_START_BE)) - break; - UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_FLT_START_BE); - } - if (ana_list & AN_FLT_XFER_DATA) { if (!flt_xfer_data(s, res, AN_FLT_XFER_DATA)) break;