Skip to content

Commit 53de6da

Browse files
committed
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.
1 parent c9fa78e commit 53de6da

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

include/haproxy/stream-t.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ struct stream {
292292

293293
struct {
294294
void *ptr; /* Pointer on the entity (def: NULL) */
295-
int type; /* entity type (0: undef, 1: rule) */
295+
int type; /* entity type (0: undef, 1: rule, 2: filter) */
296296
} last_entity; /* last evaluated entity that interrupted processing */
297297

298298
unsigned int stream_epoch; /* copy of stream_epoch when the stream was created */

src/filters.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ static int handle_analyzer_result(struct stream *s, struct channel *chn, unsigne
7272

7373
#define BREAK_EXECUTION(strm, chn, label) \
7474
do { \
75-
strm_flt(strm)->current[CHN_IDX(chn)] = filter; \
75+
if (ret < 0) { \
76+
(strm)->last_entity.type = 2; \
77+
(strm)->last_entity.ptr = filter; \
78+
} \
79+
strm_flt(strm)->current[CHN_IDX(chn)] = filter; \
7680
goto label; \
7781
} while (0)
7882

@@ -556,8 +560,11 @@ flt_set_stream_backend(struct stream *s, struct proxy *be)
556560
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
557561
if (FLT_OPS(filter)->stream_set_backend) {
558562
filter->calls++;
559-
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
563+
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0) {
564+
s->last_entity.type = 2;
565+
s->last_entity.ptr = filter;
560566
return -1;
567+
}
561568
}
562569
}
563570
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)
693700
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
694701
filter->calls++;
695702
ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, data - offset);
696-
if (ret < 0)
703+
if (ret < 0) {
704+
s->last_entity.type = 2;
705+
s->last_entity.ptr = filter;
697706
goto end;
707+
}
698708
data = ret + *flt_off - *strm_off;
699709
*flt_off += ret;
700710
}
@@ -832,8 +842,11 @@ flt_post_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
832842
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
833843
filter->calls++;
834844
ret = FLT_OPS(filter)->channel_post_analyze(s, filter, chn, an_bit);
835-
if (ret < 0)
845+
if (ret < 0) {
846+
s->last_entity.type = 2;
847+
s->last_entity.ptr = filter;
836848
break;
849+
}
837850
filter->post_analyzers &= ~an_bit;
838851
}
839852
}
@@ -986,8 +999,11 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
986999
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
9871000
filter->calls++;
9881001
ret = FLT_OPS(filter)->tcp_payload(s, filter, chn, out + offset, data - offset);
989-
if (ret < 0)
1002+
if (ret < 0) {
1003+
s->last_entity.type = 2;
1004+
s->last_entity.ptr = filter;
9901005
goto end;
1006+
}
9911007
data = ret + *flt_off - *strm_off;
9921008
*flt_off += ret;
9931009
}

src/stream.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4137,6 +4137,21 @@ static int smp_fetch_last_entity(const struct arg *args, struct sample *smp, con
41374137
trash->data = snprintf(trash->area, trash->size, "%s:%d", rule->conf.file, rule->conf.line);
41384138
smp->data.u.str = *trash;
41394139
}
4140+
else if (smp->strm->last_entity.type == 2) {
4141+
struct filter *filter = smp->strm->last_entity.ptr;
4142+
4143+
if (FLT_ID(filter)) {
4144+
smp->flags |= SMP_F_CONST;
4145+
smp->data.u.str.area = (char *)FLT_ID(filter);
4146+
smp->data.u.str.data = strlen(FLT_ID(filter));
4147+
}
4148+
else {
4149+
struct buffer *trash = get_trash_chunk();
4150+
4151+
trash->data = snprintf(trash->area, trash->size, "%p", filter->config);
4152+
smp->data.u.str = *trash;
4153+
}
4154+
}
41404155
else
41414156
return 0;
41424157

0 commit comments

Comments
 (0)