MINOR: stream: Save the last filter evaluated interrupting the processing

It is very similar to the last evaluated rule. When a filter returns an
error that interrupts the processing, it is saved in the stream, in the
last_entity field, with the type 2. The pointer on filter config is
saved. This pointer never changes during runtime and is part of the proxy's
structure. It is an element of the filter_configs list in the proxy
structure.

"last_entity" sample fetch was update accordingly. The filter identifier is
returned, if defined. Otherwise the save pointer.
This commit is contained in:
Christopher Faulet 2024-10-31 11:30:46 +01:00
parent c9fa78e747
commit 53de6da1c0
3 changed files with 37 additions and 6 deletions

View File

@ -292,7 +292,7 @@ struct stream {
struct {
void *ptr; /* Pointer on the entity (def: NULL) */
int type; /* entity type (0: undef, 1: rule) */
int type; /* entity type (0: undef, 1: rule, 2: filter) */
} last_entity; /* last evaluated entity that interrupted processing */
unsigned int stream_epoch; /* copy of stream_epoch when the stream was created */

View File

@ -72,7 +72,11 @@ static int handle_analyzer_result(struct stream *s, struct channel *chn, unsigne
#define BREAK_EXECUTION(strm, chn, label) \
do { \
strm_flt(strm)->current[CHN_IDX(chn)] = filter; \
if (ret < 0) { \
(strm)->last_entity.type = 2; \
(strm)->last_entity.ptr = filter; \
} \
strm_flt(strm)->current[CHN_IDX(chn)] = filter; \
goto label; \
} while (0)
@ -556,8 +560,11 @@ flt_set_stream_backend(struct stream *s, struct proxy *be)
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
if (FLT_OPS(filter)->stream_set_backend) {
filter->calls++;
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0) {
s->last_entity.type = 2;
s->last_entity.ptr = filter;
return -1;
}
}
}
if (be->be_req_ana & AN_REQ_FLT_START_BE) {
@ -693,8 +700,11 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, data - offset);
if (ret < 0)
if (ret < 0) {
s->last_entity.type = 2;
s->last_entity.ptr = filter;
goto end;
}
data = ret + *flt_off - *strm_off;
*flt_off += ret;
}
@ -832,8 +842,11 @@ flt_post_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->channel_post_analyze(s, filter, chn, an_bit);
if (ret < 0)
if (ret < 0) {
s->last_entity.type = 2;
s->last_entity.ptr = filter;
break;
}
filter->post_analyzers &= ~an_bit;
}
}
@ -986,8 +999,11 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
filter->calls++;
ret = FLT_OPS(filter)->tcp_payload(s, filter, chn, out + offset, data - offset);
if (ret < 0)
if (ret < 0) {
s->last_entity.type = 2;
s->last_entity.ptr = filter;
goto end;
}
data = ret + *flt_off - *strm_off;
*flt_off += ret;
}

View File

@ -4137,6 +4137,21 @@ static int smp_fetch_last_entity(const struct arg *args, struct sample *smp, con
trash->data = snprintf(trash->area, trash->size, "%s:%d", rule->conf.file, rule->conf.line);
smp->data.u.str = *trash;
}
else if (smp->strm->last_entity.type == 2) {
struct filter *filter = smp->strm->last_entity.ptr;
if (FLT_ID(filter)) {
smp->flags |= SMP_F_CONST;
smp->data.u.str.area = (char *)FLT_ID(filter);
smp->data.u.str.data = strlen(FLT_ID(filter));
}
else {
struct buffer *trash = get_trash_chunk();
trash->data = snprintf(trash->area, trash->size, "%p", filter->config);
smp->data.u.str = *trash;
}
}
else
return 0;