1 /*
2  * Stream filters related variables and functions.
3  *
4  * Copyright (C) 2015 Qualys Inc., Christopher Faulet <cfaulet@qualys.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  */
12 
13 #include <common/buffer.h>
14 #include <common/debug.h>
15 #include <common/cfgparse.h>
16 #include <common/compat.h>
17 #include <common/config.h>
18 #include <common/errors.h>
19 #include <common/htx.h>
20 #include <common/initcall.h>
21 #include <common/namespace.h>
22 #include <common/standard.h>
23 #include <common/hathreads.h>
24 
25 #include <types/filters.h>
26 #include <types/proto_http.h>
27 
28 #include <proto/compression.h>
29 #include <proto/filters.h>
30 #include <proto/flt_http_comp.h>
31 #include <proto/http_htx.h>
32 #include <proto/proto_http.h>
33 #include <proto/stream.h>
34 #include <proto/stream_interface.h>
35 
36 /* Pool used to allocate filters */
37 DECLARE_STATIC_POOL(pool_head_filter, "filter", sizeof(struct filter));
38 
39 static int handle_analyzer_result(struct stream *s, struct channel *chn, unsigned int an_bit, int ret);
40 
41 /* - RESUME_FILTER_LOOP and RESUME_FILTER_END must always be used together.
42  *   The first one begins a loop and the seconds one ends it.
43  *
44  * - BREAK_EXECUTION must be used to break the loop and set the filter from
45  *   which to resume the next time.
46  *
47  *  Here is an example:
48  *
49  *    RESUME_FILTER_LOOP(stream, channel) {
50  *        ...
51  *        if (cond)
52  *             BREAK_EXECUTION(stream, channel, label);
53  *        ...
54  *    } RESUME_FILTER_END;
55  *    ...
56  *     label:
57  *    ...
58  *
59  */
60 #define RESUME_FILTER_LOOP(strm, chn)					\
61 	do {								\
62 		struct filter *filter;					\
63 									\
64 		if (strm_flt(strm)->current[CHN_IDX(chn)]) {	\
65 			filter = strm_flt(strm)->current[CHN_IDX(chn)]; \
66 			strm_flt(strm)->current[CHN_IDX(chn)] = NULL; \
67 			goto resume_execution;				\
68 		}							\
69 									\
70 		list_for_each_entry(filter, &strm_flt(s)->filters, list) { \
71 		resume_execution:
72 
73 #define RESUME_FILTER_END					\
74 		}						\
75 	} while(0)
76 
77 #define BREAK_EXECUTION(strm, chn, label)				\
78 	do {								\
79 		strm_flt(strm)->current[CHN_IDX(chn)] = filter;	\
80 		goto label;						\
81 	} while (0)
82 
83 
84 /* List head of all known filter keywords */
85 static struct flt_kw_list flt_keywords = {
86 	.list = LIST_HEAD_INIT(flt_keywords.list)
87 };
88 
89 /*
90  * Registers the filter keyword list <kwl> as a list of valid keywords for next
91  * parsing sessions.
92  */
93 void
flt_register_keywords(struct flt_kw_list * kwl)94 flt_register_keywords(struct flt_kw_list *kwl)
95 {
96 	LIST_ADDQ(&flt_keywords.list, &kwl->list);
97 }
98 
99 /*
100  * Returns a pointer to the filter keyword <kw>, or NULL if not found. If the
101  * keyword is found with a NULL ->parse() function, then an attempt is made to
102  * find one with a valid ->parse() function. This way it is possible to declare
103  * platform-dependant, known keywords as NULL, then only declare them as valid
104  * if some options are met. Note that if the requested keyword contains an
105  * opening parenthesis, everything from this point is ignored.
106  */
107 struct flt_kw *
flt_find_kw(const char * kw)108 flt_find_kw(const char *kw)
109 {
110 	int index;
111 	const char *kwend;
112 	struct flt_kw_list *kwl;
113 	struct flt_kw *ret = NULL;
114 
115 	kwend = strchr(kw, '(');
116 	if (!kwend)
117 		kwend = kw + strlen(kw);
118 
119 	list_for_each_entry(kwl, &flt_keywords.list, list) {
120 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
121 			if ((strncmp(kwl->kw[index].kw, kw, kwend - kw) == 0) &&
122 			    kwl->kw[index].kw[kwend-kw] == 0) {
123 				if (kwl->kw[index].parse)
124 					return &kwl->kw[index]; /* found it !*/
125 				else
126 					ret = &kwl->kw[index];  /* may be OK */
127 			}
128 		}
129 	}
130 	return ret;
131 }
132 
133 /*
134  * Dumps all registered "filter" keywords to the <out> string pointer. The
135  * unsupported keywords are only dumped if their supported form was not found.
136  */
137 void
flt_dump_kws(char ** out)138 flt_dump_kws(char **out)
139 {
140 	struct flt_kw_list *kwl;
141 	int index;
142 
143 	*out = NULL;
144 	list_for_each_entry(kwl, &flt_keywords.list, list) {
145 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
146 			if (kwl->kw[index].parse ||
147 			    flt_find_kw(kwl->kw[index].kw) == &kwl->kw[index]) {
148 				memprintf(out, "%s[%4s] %s%s\n", *out ? *out : "",
149 				          kwl->scope,
150 				          kwl->kw[index].kw,
151 				          kwl->kw[index].parse ? "" : " (not supported)");
152 			}
153 		}
154 	}
155 }
156 
157 /*
158  * Lists the known filters on <out>
159  */
160 void
list_filters(FILE * out)161 list_filters(FILE *out)
162 {
163 	char *filters, *p, *f;
164 
165 	fprintf(out, "Available filters :\n");
166 	flt_dump_kws(&filters);
167 	for (p = filters; (f = strtok_r(p,"\n",&p));)
168 		fprintf(out, "\t%s\n", f);
169 	free(filters);
170 }
171 
172 /*
173  * Parses the "filter" keyword. All keywords must be handled by filters
174  * themselves
175  */
176 static int
parse_filter(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)177 parse_filter(char **args, int section_type, struct proxy *curpx,
178 	     struct proxy *defpx, const char *file, int line, char **err)
179 {
180 	struct flt_conf *fconf = NULL;
181 
182 	/* Filter cannot be defined on a default proxy */
183 	if (curpx == defpx) {
184 		memprintf(err, "parsing [%s:%d] : %s is not allowed in a 'default' section.",
185 			  file, line, args[0]);
186 		return -1;
187 	}
188 	if (!strcmp(args[0], "filter")) {
189 		struct flt_kw *kw;
190 		int cur_arg;
191 
192 		if (!*args[1]) {
193 			memprintf(err,
194 				  "parsing [%s:%d] : missing argument for '%s' in %s '%s'.",
195 				  file, line, args[0], proxy_type_str(curpx), curpx->id);
196 			goto error;
197 		}
198 		fconf = calloc(1, sizeof(*fconf));
199 		if (!fconf) {
200 			memprintf(err, "'%s' : out of memory", args[0]);
201 			goto error;
202 		}
203 
204 		cur_arg = 1;
205 		kw = flt_find_kw(args[cur_arg]);
206 		if (kw) {
207 			if (!kw->parse) {
208 				memprintf(err, "parsing [%s:%d] : '%s' : "
209 					  "'%s' option is not implemented in this version (check build options).",
210 					  file, line, args[0], args[cur_arg]);
211 				goto error;
212 			}
213 			if (kw->parse(args, &cur_arg, curpx, fconf, err, kw->private) != 0) {
214 				if (err && *err)
215 					memprintf(err, "'%s' : '%s'",
216 						  args[0], *err);
217 				else
218 					memprintf(err, "'%s' : error encountered while processing '%s'",
219 						  args[0], args[cur_arg]);
220 				goto error;
221 			}
222 		}
223 		else {
224 			flt_dump_kws(err);
225 			indent_msg(err, 4);
226 			memprintf(err, "'%s' : unknown keyword '%s'.%s%s",
227 			          args[0], args[cur_arg],
228 			          err && *err ? " Registered keywords :" : "", err && *err ? *err : "");
229 			goto error;
230 		}
231 		if (*args[cur_arg]) {
232 			memprintf(err, "'%s %s' : unknown keyword '%s'.",
233 			          args[0], args[1], args[cur_arg]);
234 			goto error;
235 		}
236 		if (fconf->ops == NULL) {
237 			memprintf(err, "'%s %s' : no callbacks defined.",
238 			          args[0], args[1]);
239 			goto error;
240 		}
241 
242 		LIST_ADDQ(&curpx->filter_configs, &fconf->list);
243 	}
244 	return 0;
245 
246   error:
247 	free(fconf);
248 	return -1;
249 
250 
251 }
252 
253 /*
254  * Calls 'init' callback for all filters attached to a proxy. This happens after
255  * the configuration parsing. Filters can finish to fill their config. Returns
256  * (ERR_ALERT|ERR_FATAL) if an error occurs, 0 otherwise.
257  */
258 static int
flt_init(struct proxy * proxy)259 flt_init(struct proxy *proxy)
260 {
261 	struct flt_conf *fconf;
262 
263 	list_for_each_entry(fconf, &proxy->filter_configs, list) {
264 		if (fconf->ops->init && fconf->ops->init(proxy, fconf) < 0)
265 			return ERR_ALERT|ERR_FATAL;
266 	}
267 	return 0;
268 }
269 
270 /*
271  * Calls 'init_per_thread' callback for all filters attached to a proxy for each
272  * threads. This happens after the thread creation. Filters can finish to fill
273  * their config. Returns (ERR_ALERT|ERR_FATAL) if an error occurs, 0 otherwise.
274  */
275 static int
flt_init_per_thread(struct proxy * proxy)276 flt_init_per_thread(struct proxy *proxy)
277 {
278 	struct flt_conf *fconf;
279 
280 	list_for_each_entry(fconf, &proxy->filter_configs, list) {
281 		if (fconf->ops->init_per_thread && fconf->ops->init_per_thread(proxy, fconf) < 0)
282 			return ERR_ALERT|ERR_FATAL;
283 	}
284 	return 0;
285 }
286 
287 /* Calls flt_init() for all proxies, see above */
288 static int
flt_init_all()289 flt_init_all()
290 {
291 	struct proxy *px;
292 	int err_code = 0;
293 
294 	for (px = proxies_list; px; px = px->next) {
295 		if (px->state == PR_STSTOPPED) {
296 			flt_deinit(px);
297 			continue;
298 		}
299 		err_code |= flt_init(px);
300 		if (err_code & (ERR_ABORT|ERR_FATAL)) {
301 			ha_alert("Failed to initialize filters for proxy '%s'.\n",
302 				 px->id);
303 			return err_code;
304 		}
305 	}
306 	return 0;
307 }
308 
309 /* Calls flt_init_per_thread() for all proxies, see above.  Be careful here, it
310  * returns 0 if an error occurred. This is the opposite of flt_init_all. */
311 static int
flt_init_all_per_thread()312 flt_init_all_per_thread()
313 {
314 	struct proxy *px;
315 	int err_code = 0;
316 
317 	for (px = proxies_list; px; px = px->next) {
318 		if (px->state == PR_STSTOPPED)
319 			continue;
320 
321 		err_code = flt_init_per_thread(px);
322 		if (err_code & (ERR_ABORT|ERR_FATAL)) {
323 			ha_alert("Failed to initialize filters for proxy '%s' for thread %u.\n",
324 				 px->id, tid);
325 			return 0;
326 		}
327 	}
328 	return 1;
329 }
330 
331 /*
332  * Calls 'check' callback for all filters attached to a proxy. This happens
333  * after the configuration parsing but before filters initialization. Returns
334  * the number of encountered errors.
335  */
336 int
flt_check(struct proxy * proxy)337 flt_check(struct proxy *proxy)
338 {
339 	struct flt_conf *fconf;
340 	int err = 0;
341 
342 	err += check_implicit_http_comp_flt(proxy);
343 	list_for_each_entry(fconf, &proxy->filter_configs, list) {
344 		if (fconf->ops->check)
345 			err += fconf->ops->check(proxy, fconf);
346 	}
347 	return err;
348 }
349 
350 /*
351  * Calls 'denit' callback for all filters attached to a proxy. This happens when
352  * HAProxy is stopped.
353  */
354 void
flt_deinit(struct proxy * proxy)355 flt_deinit(struct proxy *proxy)
356 {
357 	struct flt_conf *fconf, *back;
358 
359 	list_for_each_entry_safe(fconf, back, &proxy->filter_configs, list) {
360 		if (fconf->ops->deinit)
361 			fconf->ops->deinit(proxy, fconf);
362 		LIST_DEL(&fconf->list);
363 		free(fconf);
364 	}
365 }
366 
367 /*
368  * Calls 'denit_per_thread' callback for all filters attached to a proxy for
369  * each threads. This happens before exiting a thread.
370  */
371 void
flt_deinit_per_thread(struct proxy * proxy)372 flt_deinit_per_thread(struct proxy *proxy)
373 {
374 	struct flt_conf *fconf, *back;
375 
376 	list_for_each_entry_safe(fconf, back, &proxy->filter_configs, list) {
377 		if (fconf->ops->deinit_per_thread)
378 			fconf->ops->deinit_per_thread(proxy, fconf);
379 	}
380 }
381 
382 
383 /* Calls flt_deinit_per_thread() for all proxies, see above */
384 static void
flt_deinit_all_per_thread()385 flt_deinit_all_per_thread()
386 {
387 	struct proxy *px;
388 
389 	for (px = proxies_list; px; px = px->next)
390 		flt_deinit_per_thread(px);
391 }
392 
393 /* Attaches a filter to a stream. Returns -1 if an error occurs, 0 otherwise. */
394 static int
flt_stream_add_filter(struct stream * s,struct flt_conf * fconf,unsigned int flags)395 flt_stream_add_filter(struct stream *s, struct flt_conf *fconf, unsigned int flags)
396 {
397 	struct filter *f;
398 
399 	if (IS_HTX_STRM(s) && !(fconf->flags & FLT_CFG_FL_HTX))
400 		return 0;
401 
402 	f = pool_alloc(pool_head_filter);
403 	if (!f) /* not enough memory */
404 		return -1;
405 	memset(f, 0, sizeof(*f));
406 	f->config = fconf;
407 	f->flags |= flags;
408 
409 	if (FLT_OPS(f)->attach) {
410 		int ret = FLT_OPS(f)->attach(s, f);
411 		if (ret <= 0) {
412 			pool_free(pool_head_filter, f);
413 			return ret;
414 		}
415 	}
416 
417 	LIST_ADDQ(&strm_flt(s)->filters, &f->list);
418 	strm_flt(s)->flags |= STRM_FLT_FL_HAS_FILTERS;
419 	return 0;
420 }
421 
422 /*
423  * Called when a stream is created. It attaches all frontend filters to the
424  * stream. Returns -1 if an error occurs, 0 otherwise.
425  */
426 int
flt_stream_init(struct stream * s)427 flt_stream_init(struct stream *s)
428 {
429 	struct flt_conf *fconf;
430 
431 	memset(strm_flt(s), 0, sizeof(*strm_flt(s)));
432 	LIST_INIT(&strm_flt(s)->filters);
433 	list_for_each_entry(fconf, &strm_fe(s)->filter_configs, list) {
434 		if (flt_stream_add_filter(s, fconf, 0) < 0)
435 			return -1;
436 	}
437 	return 0;
438 }
439 
440 /*
441  * Called when a stream is closed or when analyze ends (For an HTTP stream, this
442  * happens after each request/response exchange). When analyze ends, backend
443  * filters are removed. When the stream is closed, all filters attached to the
444  * stream are removed.
445  */
446 void
flt_stream_release(struct stream * s,int only_backend)447 flt_stream_release(struct stream *s, int only_backend)
448 {
449 	struct filter *filter, *back;
450 
451 	list_for_each_entry_safe(filter, back, &strm_flt(s)->filters, list) {
452 		if (!only_backend || (filter->flags & FLT_FL_IS_BACKEND_FILTER)) {
453 			if (FLT_OPS(filter)->detach)
454 				FLT_OPS(filter)->detach(s, filter);
455 			LIST_DEL(&filter->list);
456 			pool_free(pool_head_filter, filter);
457 		}
458 	}
459 	if (LIST_ISEMPTY(&strm_flt(s)->filters))
460 		strm_flt(s)->flags &= ~STRM_FLT_FL_HAS_FILTERS;
461 }
462 
463 /*
464  * Calls 'stream_start' for all filters attached to a stream. This happens when
465  * the stream is created, just after calling flt_stream_init
466  * function. Returns -1 if an error occurs, 0 otherwise.
467  */
468 int
flt_stream_start(struct stream * s)469 flt_stream_start(struct stream *s)
470 {
471 	struct filter *filter;
472 
473 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
474 		if (FLT_OPS(filter)->stream_start && FLT_OPS(filter)->stream_start(s, filter) < 0)
475 			return -1;
476 	}
477 	if (strm_li(s) && (strm_li(s)->analysers & AN_REQ_FLT_START_FE)) {
478 		s->req.flags |= CF_FLT_ANALYZE;
479 		s->req.analysers |= AN_REQ_FLT_END;
480 	}
481 	return 0;
482 }
483 
484 /*
485  * Calls 'stream_stop' for all filters attached to a stream. This happens when
486  * the stream is stopped, just before calling flt_stream_release function.
487  */
488 void
flt_stream_stop(struct stream * s)489 flt_stream_stop(struct stream *s)
490 {
491 	struct filter *filter;
492 
493 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
494 		if (FLT_OPS(filter)->stream_stop)
495 			FLT_OPS(filter)->stream_stop(s, filter);
496 	}
497 }
498 
499 /*
500  * Calls 'check_timeouts' for all filters attached to a stream. This happens when
501  * the stream is woken up because of expired timer.
502  */
503 void
flt_stream_check_timeouts(struct stream * s)504 flt_stream_check_timeouts(struct stream *s)
505 {
506 	struct filter *filter;
507 
508 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
509 		if (FLT_OPS(filter)->check_timeouts)
510 			FLT_OPS(filter)->check_timeouts(s, filter);
511 	}
512 }
513 
514 /*
515  * Called when a backend is set for a stream. If the frontend and the backend
516  * are not the same, this function attaches all backend filters to the
517  * stream. Returns -1 if an error occurs, 0 otherwise.
518  */
519 int
flt_set_stream_backend(struct stream * s,struct proxy * be)520 flt_set_stream_backend(struct stream *s, struct proxy *be)
521 {
522 	struct flt_conf *fconf;
523 	struct filter   *filter;
524 
525 	if (strm_fe(s) == be)
526 		goto end;
527 
528 	list_for_each_entry(fconf, &be->filter_configs, list) {
529 		if (flt_stream_add_filter(s, fconf, FLT_FL_IS_BACKEND_FILTER) < 0)
530 			return -1;
531 	}
532 
533   end:
534 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
535 		if (FLT_OPS(filter)->stream_set_backend &&
536 		    FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
537 			return -1;
538 	}
539 	if (be->be_req_ana & AN_REQ_FLT_START_BE) {
540 		s->req.flags |= CF_FLT_ANALYZE;
541 		s->req.analysers |= AN_REQ_FLT_END;
542 	}
543 	if ((strm_fe(s)->fe_rsp_ana | be->be_rsp_ana) & (AN_RES_FLT_START_FE|AN_RES_FLT_START_BE)) {
544 		s->res.flags |= CF_FLT_ANALYZE;
545 		s->res.analysers |= AN_RES_FLT_END;
546 	}
547 
548 	return 0;
549 }
550 
551 /*
552  * Calls 'http_data' callback for all "data" filters attached to a stream. This
553  * function is called when incoming data are available (excluding chunks
554  * envelope for chunked messages) in the AN_REQ_HTTP_XFER_BODY and
555  * AN_RES_HTTP_XFER_BODY analyzers. It takes care to update the next offset of
556  * filters and adjusts available data to be sure that a filter cannot parse more
557  * data than its predecessors. A filter can choose to not consume all available
558  * data. Returns -1 if an error occurs, the number of consumed bytes otherwise.
559  *
560  * DEPRECATED FUNCTION - CALLED FROM LEGACY HTTP ANALYZERS
561  */
562 int
flt_http_data(struct stream * s,struct http_msg * msg)563 flt_http_data(struct stream *s, struct http_msg *msg)
564 {
565 	struct filter *filter;
566 	unsigned int   buf_i;
567 	int            delta = 0, ret = 0;
568 
569 	/* Save buffer state */
570 	buf_i = ci_data(msg->chn);
571 
572 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
573 		unsigned int *nxt;
574 
575 		/* Call "data" filters only */
576 		if (!IS_DATA_FILTER(filter, msg->chn))
577 			continue;
578 
579 		/* If the HTTP parser is ahead, we update the next offset of the
580 		 * current filter. This happens for chunked messages, at the
581 		 * beginning of a new chunk. */
582 		nxt = &FLT_NXT(filter, msg->chn);
583 		if (msg->next > *nxt)
584 			*nxt = msg->next;
585 
586 		if (FLT_OPS(filter)->http_data) {
587 			unsigned int i = ci_data(msg->chn);
588 
589 			ret = FLT_OPS(filter)->http_data(s, filter, msg);
590 			if (ret < 0)
591 				break;
592 			delta += (int)(ci_data(msg->chn) - i);
593 
594 			/* Update the next offset of the current filter */
595 			*nxt += ret;
596 
597 			/* And set this value as the bound for the next
598 			 * filter. It will not able to parse more data than this
599 			 * one. */
600 			b_set_data(&msg->chn->buf, co_data(msg->chn) + *nxt);
601 		}
602 		else {
603 			/* Consume all available data and update the next offset
604 			 * of the current filter. buf->i is untouched here. */
605 			ret = MIN(msg->chunk_len + msg->next, ci_data(msg->chn)) - *nxt;
606 			*nxt += ret;
607 		}
608 	}
609 
610 	/* Restore the original buffer state */
611 	b_set_data(&msg->chn->buf, co_data(msg->chn) + buf_i + delta);
612 
613 	return ret;
614 }
615 
616 /*
617  * Calls 'http_chunk_trailers' callback for all "data" filters attached to a
618  * stream. This function is called for chunked messages only when a part of the
619  * trailers was parsed in the AN_REQ_HTTP_XFER_BODY and AN_RES_HTTP_XFER_BODY
620  * analyzers. Filters can know how much data were parsed by the HTTP parsing
621  * until the last call with the msg->sol value. Returns a negative value if an
622  * error occurs, any other value otherwise.
623  *
624  * DEPRECATED FUNCTION - CALLED FROM LEGACY HTTP ANALYZERS
625  */
626 int
flt_http_chunk_trailers(struct stream * s,struct http_msg * msg)627 flt_http_chunk_trailers(struct stream *s, struct http_msg *msg)
628 {
629 	struct filter *filter;
630 	int            ret = 1;
631 
632 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
633 		unsigned int *nxt;
634 
635 		/* Call "data" filters only */
636 		if (!IS_DATA_FILTER(filter, msg->chn))
637 			continue;
638 
639 		/* Be sure to set the next offset of the filter at the right
640 		 * place. This is really useful when the first part of the
641 		 * trailers was parsed. */
642 		nxt = &FLT_NXT(filter, msg->chn);
643 		*nxt = msg->next;
644 
645 		if (FLT_OPS(filter)->http_chunk_trailers) {
646 			ret = FLT_OPS(filter)->http_chunk_trailers(s, filter, msg);
647 			if (ret < 0)
648 				break;
649 		}
650 		/* Update the next offset of the current filter. Here all data
651 		 * are always consumed. */
652 		*nxt += msg->sol;
653 	}
654 	return ret;
655 }
656 
657 /*
658  * Calls 'http_end' callback for all filters attached to a stream. All filters
659  * are called here, but only if there is at least one "data" filter. This
660  * functions is called when all data were parsed and forwarded. 'http_end'
661  * callback is resumable, so this function returns a negative value if an error
662  * occurs, 0 if it needs to wait for some reason, any other value otherwise.
663  *
664  * Be carefull, this function can be called from the HTTP legacy analyzers or
665  * from HTX analyzers. If your filter is compatible with the two modes, use
666  * IS_HTX_STRM macro on the stream.
667  */
668 int
flt_http_end(struct stream * s,struct http_msg * msg)669 flt_http_end(struct stream *s, struct http_msg *msg)
670 {
671 	unsigned long long *strm_off = &FLT_STRM_OFF(s, msg->chn);
672 	unsigned int offset = 0;
673 	int ret = 1;
674 
675 	RESUME_FILTER_LOOP(s, msg->chn) {
676 		unsigned long long flt_off = FLT_OFF(filter, msg->chn);
677 		offset = flt_off - *strm_off;
678 
679 		/* Call http_end for data filters only. But the filter offset is
680 		 * still valid for all filters
681 		 . */
682 		if (!IS_DATA_FILTER(filter, msg->chn))
683 			continue;
684 
685 		if (FLT_OPS(filter)->http_end) {
686 			ret = FLT_OPS(filter)->http_end(s, filter, msg);
687 			if (ret <= 0)
688 				BREAK_EXECUTION(s, msg->chn, end);
689 		}
690 	} RESUME_FILTER_END;
691 
692 	c_adv(msg->chn, offset);
693 	*strm_off += offset;
694 
695 end:
696 	return ret;
697 }
698 
699 /*
700  * Calls 'http_reset' callback for all filters attached to a stream. This
701  * happens when a 100-continue response is received.
702  *
703  * Be carefull, this function can be called from the HTTP legacy analyzers or
704  * from HTX analyzers. If your filter is compatible with the two modes, use
705  * IS_HTX_STRM macro on the stream.
706  */
707 void
flt_http_reset(struct stream * s,struct http_msg * msg)708 flt_http_reset(struct stream *s, struct http_msg *msg)
709 {
710 	struct filter *filter;
711 
712 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
713 		if (FLT_OPS(filter)->http_reset)
714 			FLT_OPS(filter)->http_reset(s, filter, msg);
715 	}
716 }
717 
718 /*
719  * Calls 'http_reply' callback for all filters attached to a stream when HA
720  * decides to stop the HTTP message processing.
721  *
722  * Be carefull, this function can be called from the HTTP legacy analyzers or
723  * from HTX analyzers. If your filter is compatible with the two modes, use
724  * IS_HTX_STRM macro on the stream.
725  */
726 void
flt_http_reply(struct stream * s,short status,const struct buffer * msg)727 flt_http_reply(struct stream *s, short status, const struct buffer *msg)
728 {
729 	struct filter *filter;
730 
731 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
732 		if (FLT_OPS(filter)->http_reply)
733 			FLT_OPS(filter)->http_reply(s, filter, status, msg);
734 	}
735 }
736 
737 /*
738  * Calls 'http_forward_data' callback for all "data" filters attached to a HTTP
739  * legacy stream. This function is called when some data can be forwarded in the
740  * AN_REQ_HTTP_XFER_BODY and AN_RES_HTTP_XFER_BODY analyzers. It takes care to
741  * update the forward offset of filters and adjusts "forwardable" data to be
742  * sure that a filter cannot forward more data than its predecessors. A filter
743  * can choose to not forward all parsed data. Returns a negative value if an
744  * error occurs, else the number of forwarded bytes.
745  *
746  * DEPRECATED FUNCTION - CALLED FROM LEGACY HTTP ANALYZERS
747  */
748 int
flt_http_forward_data(struct stream * s,struct http_msg * msg,unsigned int len)749 flt_http_forward_data(struct stream *s, struct http_msg *msg, unsigned int len)
750 {
751 	struct filter *filter;
752 	int            ret = len;
753 
754 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
755 		unsigned int *nxt, *fwd;
756 
757 		/* Call "data" filters only */
758 		if (!IS_DATA_FILTER(filter, msg->chn))
759 			continue;
760 
761 		/* If the HTTP parser is ahead, we update the next offset of the
762 		 * current filter. This happens for chunked messages, when the
763 		 * chunk envelope is parsed. */
764 		nxt = &FLT_NXT(filter, msg->chn);
765 		fwd = &FLT_FWD(filter, msg->chn);
766 		if (msg->next > *nxt)
767 			*nxt = msg->next;
768 
769 		if (FLT_OPS(filter)->http_forward_data) {
770 			/* Remove bytes that the current filter considered as
771 			 * forwarded */
772 			ret = FLT_OPS(filter)->http_forward_data(s, filter, msg, ret - *fwd);
773 			if (ret < 0)
774 				goto end;
775 		}
776 
777 		/* Adjust bytes that the current filter considers as
778 		 * forwarded */
779 		*fwd += ret;
780 
781 		/* And set this value as the bound for the next filter. It will
782 		 * not able to forward more data than the current one. */
783 		ret = *fwd;
784 	}
785 
786 	if (!ret)
787 		goto end;
788 
789 	/* Finally, adjust filters offsets by removing data that HAProxy will
790 	 * forward. */
791 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
792 		if (!IS_DATA_FILTER(filter, msg->chn))
793 			continue;
794 		FLT_NXT(filter, msg->chn) -= ret;
795 		FLT_FWD(filter, msg->chn) -= ret;
796 	}
797  end:
798 	return ret;
799 }
800 
801 /*
802  * Calls 'http_payload' callback for all "data" filters attached to a
803  * stream. This function is called when some data can be forwarded in the
804  * AN_REQ_HTTP_XFER_BODY and AN_RES_HTTP_XFER_BODY analyzers. It takes care to
805  * update the filters and the stream offset to be sure that a filter cannot
806  * forward more data than its predecessors. A filter can choose to not forward
807  * all data. Returns a negative value if an error occurs, else the number of
808  * forwarded bytes.
809  *
810  * Be carefull, this callback is only called from HTX analyzers. So the
811  * channel's buffer must be considered as an HTX structured. Of course, your
812  * filter must support HTX streams.
813  */
814 int
flt_http_payload(struct stream * s,struct http_msg * msg,unsigned int len)815 flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
816 {
817 	struct filter *filter;
818 	unsigned long long *strm_off = &FLT_STRM_OFF(s, msg->chn);
819 	unsigned int out = co_data(msg->chn);
820 	int ret, data;
821 
822 	strm_flt(s)->flags &= ~STRM_FLT_FL_HOLD_HTTP_HDRS;
823 
824 	ret = data = len - out;
825 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
826 		unsigned long long *flt_off = &FLT_OFF(filter, msg->chn);
827 		unsigned int offset = *flt_off - *strm_off;
828 
829 		/* Call http_payload for filters only. Forward all data for
830 		 * others and update the filter offset
831 		 */
832 		if (!IS_DATA_FILTER(filter, msg->chn)) {
833 			*flt_off += data - offset;
834 			continue;
835 		}
836 
837 		if (FLT_OPS(filter)->http_payload) {
838 			ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, data - offset);
839 			if (ret < 0)
840 				goto end;
841 			data = ret + *flt_off - *strm_off;
842 			*flt_off += ret;
843 		}
844 	}
845 
846 	/* If nothing was forwarded yet, we take care to hold the headers if
847 	 * following conditions are met :
848 	 *
849 	 *  - *strm_off == 0 (nothing forwarded yet)
850 	 *  - ret == 0       (no data forwarded at all on this turn)
851 	 *  - STRM_FLT_FL_HOLD_HTTP_HDRS flag set (at least one filter want to hold the headers)
852 	 *
853 	 * Be careful, STRM_FLT_FL_HOLD_HTTP_HDRS is removed before each http_payload loop.
854 	 * Thus, it must explicitly be set when necessary. We must do that to hold the headers
855 	 * when there is no payload.
856 	 */
857 	if (!ret && !*strm_off && (strm_flt(s)->flags & STRM_FLT_FL_HOLD_HTTP_HDRS))
858 		goto end;
859 
860 	ret = data;
861 	*strm_off += ret;
862  end:
863 	return ret;
864 }
865 
866 /*
867  * Calls 'channel_start_analyze' callback for all filters attached to a
868  * stream. This function is called when we start to analyze a request or a
869  * response. For frontend filters, it is called before all other analyzers. For
870  * backend ones, it is called before all backend
871  * analyzers. 'channel_start_analyze' callback is resumable, so this function
872  * returns 0 if an error occurs or if it needs to wait, any other value
873  * otherwise.
874  */
875 int
flt_start_analyze(struct stream * s,struct channel * chn,unsigned int an_bit)876 flt_start_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
877 {
878 	int ret = 1;
879 
880 	/* If this function is called, this means there is at least one filter,
881 	 * so we do not need to check the filter list's emptiness. */
882 
883 	/* Set flag on channel to tell that the channel is filtered */
884 	chn->flags |= CF_FLT_ANALYZE;
885 	chn->analysers |= ((chn->flags & CF_ISRESP) ? AN_RES_FLT_END : AN_REQ_FLT_END);
886 
887 	RESUME_FILTER_LOOP(s, chn) {
888 		if (!(chn->flags & CF_ISRESP)) {
889 			if (an_bit == AN_REQ_FLT_START_BE &&
890 			    !(filter->flags & FLT_FL_IS_BACKEND_FILTER))
891 				continue;
892 		}
893 		else {
894 			if (an_bit == AN_RES_FLT_START_BE &&
895 			    !(filter->flags & FLT_FL_IS_BACKEND_FILTER))
896 				continue;
897 		}
898 
899 		FLT_NXT(filter, chn) = 0;
900 		FLT_FWD(filter, chn) = 0;
901 
902 		if (FLT_OPS(filter)->channel_start_analyze) {
903 			ret = FLT_OPS(filter)->channel_start_analyze(s, filter, chn);
904 			if (ret <= 0)
905 				BREAK_EXECUTION(s, chn, end);
906 		}
907 	} RESUME_FILTER_END;
908 
909  end:
910 	return handle_analyzer_result(s, chn, an_bit, ret);
911 }
912 
913 /*
914  * Calls 'channel_pre_analyze' callback for all filters attached to a
915  * stream. This function is called BEFORE each analyzer attached to a channel,
916  * expects analyzers responsible for data sending. 'channel_pre_analyze'
917  * callback is resumable, so this function returns 0 if an error occurs or if it
918  * needs to wait, any other value otherwise.
919  *
920  * Note this function can be called many times for the same analyzer. In fact,
921  * it is called until the analyzer finishes its processing.
922  */
923 int
flt_pre_analyze(struct stream * s,struct channel * chn,unsigned int an_bit)924 flt_pre_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
925 {
926 	int ret = 1;
927 
928 	RESUME_FILTER_LOOP(s, chn) {
929 		if (FLT_OPS(filter)->channel_pre_analyze && (filter->pre_analyzers & an_bit)) {
930 			ret = FLT_OPS(filter)->channel_pre_analyze(s, filter, chn, an_bit);
931 			if (ret <= 0)
932 				BREAK_EXECUTION(s, chn, check_result);
933 			filter->pre_analyzers &= ~an_bit;
934 		}
935 	} RESUME_FILTER_END;
936 
937  check_result:
938 	return handle_analyzer_result(s, chn, 0, ret);
939 }
940 
941 /*
942  * Calls 'channel_post_analyze' callback for all filters attached to a
943  * stream. This function is called AFTER each analyzer attached to a channel,
944  * expects analyzers responsible for data sending. 'channel_post_analyze'
945  * callback is NOT resumable, so this function returns a 0 if an error occurs,
946  * any other value otherwise.
947  *
948  * Here, AFTER means when the analyzer finishes its processing.
949  */
950 int
flt_post_analyze(struct stream * s,struct channel * chn,unsigned int an_bit)951 flt_post_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
952 {
953 	struct filter *filter;
954 	int            ret = 1;
955 
956 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
957 		if (FLT_OPS(filter)->channel_post_analyze &&  (filter->post_analyzers & an_bit)) {
958 			ret = FLT_OPS(filter)->channel_post_analyze(s, filter, chn, an_bit);
959 			if (ret < 0)
960 				break;
961 			filter->post_analyzers &= ~an_bit;
962 		}
963 	}
964 	return handle_analyzer_result(s, chn, 0, ret);
965 }
966 
967 /*
968  * This function is the AN_REQ/RES_FLT_HTTP_HDRS analyzer, used to filter HTTP
969  * headers or a request or a response. Returns 0 if an error occurs or if it
970  * needs to wait, any other value otherwise.
971  *
972  * Be carefull, this function can be called from the HTTP legacy analyzers or
973  * from HTX analyzers. If your filter is compatible with the two modes, use
974  * IS_HTX_STRM macro on the stream.
975  */
976 int
flt_analyze_http_headers(struct stream * s,struct channel * chn,unsigned int an_bit)977 flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_bit)
978 {
979 	struct filter   *filter;
980 	struct http_msg *msg;
981 	int              ret = 1;
982 
983 	msg = ((chn->flags & CF_ISRESP) ? &s->txn->rsp : &s->txn->req);
984 	RESUME_FILTER_LOOP(s, chn) {
985 		if (FLT_OPS(filter)->http_headers) {
986 			ret = FLT_OPS(filter)->http_headers(s, filter, msg);
987 			if (ret <= 0)
988 				BREAK_EXECUTION(s, chn, check_result);
989 		}
990 	} RESUME_FILTER_END;
991 
992 	if (IS_HTX_STRM(s)) {
993 		if (HAS_DATA_FILTERS(s, chn)) {
994 			size_t data = http_get_hdrs_size(htxbuf(&chn->buf));
995 			struct filter *f;
996 
997 			list_for_each_entry(f, &strm_flt(s)->filters, list)
998 				FLT_OFF(f, chn) = data;
999 		}
1000 	}
1001 	else {
1002 		/* We increase next offset of all "data" filters after all processing on
1003 		 * headers because any filter can alter them. So the definitive size of
1004 		 * headers (msg->sov) is only known when all filters have been
1005 		 * called. */
1006 		list_for_each_entry(filter, &strm_flt(s)->filters, list) {
1007 			/* Handle "data" filters only */
1008 			if (!IS_DATA_FILTER(filter, chn))
1009 				continue;
1010 			FLT_NXT(filter, chn) = msg->sov;
1011 		}
1012 	}
1013 
1014  check_result:
1015 	return handle_analyzer_result(s, chn, an_bit, ret);
1016 }
1017 
1018 /*
1019  * Calls 'channel_end_analyze' callback for all filters attached to a
1020  * stream. This function is called when we stop to analyze a request or a
1021  * response. It is called after all other analyzers. 'channel_end_analyze'
1022  * callback is resumable, so this function returns 0 if an error occurs or if it
1023  * needs to wait, any other value otherwise.
1024  */
1025 int
flt_end_analyze(struct stream * s,struct channel * chn,unsigned int an_bit)1026 flt_end_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
1027 {
1028 	int ret = 1;
1029 
1030 	/* Check if all filters attached on the stream have finished their
1031 	 * processing on this channel. */
1032 	if (!(chn->flags & CF_FLT_ANALYZE))
1033 		goto sync;
1034 
1035 	RESUME_FILTER_LOOP(s, chn) {
1036 		FLT_NXT(filter, chn) = 0;
1037 		FLT_FWD(filter, chn) = 0;
1038 		unregister_data_filter(s, chn, filter);
1039 
1040 		if (FLT_OPS(filter)->channel_end_analyze) {
1041 			ret = FLT_OPS(filter)->channel_end_analyze(s, filter, chn);
1042 			if (ret <= 0)
1043 				BREAK_EXECUTION(s, chn, end);
1044 		}
1045 	} RESUME_FILTER_END;
1046 
1047  end:
1048 	/* We don't remove yet this analyzer because we need to synchronize the
1049 	 * both channels. So here, we just remove the flag CF_FLT_ANALYZE. */
1050 	ret = handle_analyzer_result(s, chn, 0, ret);
1051 	if (ret) {
1052 		chn->flags &= ~CF_FLT_ANALYZE;
1053 
1054 		/* Pretend there is an activity on both channels. Flag on the
1055 		 * current one will be automatically removed, so only the other
1056 		 * one will remain. This is a way to be sure that
1057 		 * 'channel_end_analyze' callback will have a chance to be
1058 		 * called at least once for the other side to finish the current
1059 		 * processing. Of course, this is the filter responsibility to
1060 		 * wakeup the stream if it choose to loop on this callback. */
1061 		s->req.flags |= CF_WAKE_ONCE;
1062 		s->res.flags |= CF_WAKE_ONCE;
1063 	}
1064 
1065 
1066  sync:
1067 	/* Now we can check if filters have finished their work on the both
1068 	 * channels */
1069 	if (!(s->req.flags & CF_FLT_ANALYZE) && !(s->res.flags & CF_FLT_ANALYZE)) {
1070 		/* Sync channels by removing this analyzer for the both channels */
1071 		s->req.analysers &= ~AN_REQ_FLT_END;
1072 		s->res.analysers &= ~AN_RES_FLT_END;
1073 
1074 		/* Clean up the HTTP transaction if needed */
1075 		if (s->txn && (s->txn->flags & TX_WAIT_CLEANUP))
1076 			http_end_txn_clean_session(s);
1077 
1078 		/* Remove backend filters from the list */
1079 		flt_stream_release(s, 1);
1080 	}
1081 
1082 	return ret;
1083 }
1084 
1085 
1086 /*
1087  * Calls 'tcp_data' callback for all "data" filters attached to a stream. This
1088  * function is called when incoming data are available. It takes care to update
1089  * the next offset of filters and adjusts available data to be sure that a
1090  * filter cannot parse more data than its predecessors. A filter can choose to
1091  * not consume all available data. Returns -1 if an error occurs, the number of
1092  * consumed bytes otherwise.
1093  */
1094 static int
flt_data(struct stream * s,struct channel * chn)1095 flt_data(struct stream *s, struct channel *chn)
1096 {
1097 	struct filter *filter;
1098 	unsigned int   buf_i;
1099 	int            delta = 0, ret = 0;
1100 
1101 	/* Save buffer state */
1102 	buf_i = ci_data(chn);
1103 
1104 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
1105 		unsigned int *nxt;
1106 
1107 		/* Call "data" filters only */
1108 		if (!IS_DATA_FILTER(filter, chn))
1109 			continue;
1110 
1111 		nxt = &FLT_NXT(filter, chn);
1112 		if (FLT_OPS(filter)->tcp_data) {
1113 			unsigned int i = ci_data(chn);
1114 
1115 			ret = FLT_OPS(filter)->tcp_data(s, filter, chn);
1116 			if (ret < 0)
1117 				break;
1118 			delta += (int)(ci_data(chn) - i);
1119 
1120 			/* Increase next offset of the current filter */
1121 			*nxt += ret;
1122 
1123 			/* And set this value as the bound for the next
1124 			 * filter. It will not able to parse more data than the
1125 			 * current one. */
1126 			b_set_data(&chn->buf, co_data(chn) + *nxt);
1127 		}
1128 		else {
1129 			/* Consume all available data */
1130 			*nxt = ci_data(chn);
1131 		}
1132 
1133 		/* Update <ret> value to be sure to have the last one when we
1134 		 * exit from the loop. This value will be used to know how much
1135 		 * data are "forwardable" */
1136 		ret = *nxt;
1137 	}
1138 
1139 	/* Restore the original buffer state */
1140 	b_set_data(&chn->buf, co_data(chn) + buf_i + delta);
1141 
1142 	return ret;
1143 }
1144 
1145 /*
1146  * Calls 'tcp_forward_data' callback for all "data" filters attached to a
1147  * stream. This function is called when some data can be forwarded. It takes
1148  * care to update the forward offset of filters and adjusts "forwardable" data
1149  * to be sure that a filter cannot forward more data than its predecessors. A
1150  * filter can choose to not forward all parsed data. Returns a negative value if
1151  * an error occurs, else the number of forwarded bytes.
1152  */
1153 static int
flt_forward_data(struct stream * s,struct channel * chn,unsigned int len)1154 flt_forward_data(struct stream *s, struct channel *chn, unsigned int len)
1155 {
1156 	struct filter *filter;
1157 	int            ret = len;
1158 
1159 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
1160 		unsigned int *fwd;
1161 
1162 		/* Call "data" filters only */
1163 		if (!IS_DATA_FILTER(filter, chn))
1164 			continue;
1165 
1166 		fwd = &FLT_FWD(filter, chn);
1167 		if (FLT_OPS(filter)->tcp_forward_data) {
1168 			/* Remove bytes that the current filter considered as
1169 			 * forwarded */
1170 			ret = FLT_OPS(filter)->tcp_forward_data(s, filter, chn, ret - *fwd);
1171 			if (ret < 0)
1172 				goto end;
1173 		}
1174 
1175 		/* Adjust bytes that the current filter considers as
1176 		 * forwarded */
1177 		*fwd += ret;
1178 
1179 		/* And set this value as the bound for the next filter. It will
1180 		 * not able to forward more data than the current one. */
1181 		ret = *fwd;
1182 	}
1183 
1184 	if (!ret)
1185 		goto end;
1186 
1187 	/* Finally, adjust filters offsets by removing data that HAProxy will
1188 	 * forward. */
1189 	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
1190 		if (!IS_DATA_FILTER(filter, chn))
1191 			continue;
1192 		FLT_NXT(filter, chn) -= ret;
1193 		FLT_FWD(filter, chn) -= ret;
1194 	}
1195 
1196  end:
1197 	return ret;
1198 }
1199 
1200 /*
1201  * Called when TCP data must be filtered on a channel. This function is the
1202  * AN_REQ/RES_FLT_XFER_DATA analyzer. When called, it is responsible to forward
1203  * data when the proxy is not in http mode. Behind the scene, it calls
1204  * consecutively 'tcp_data' and 'tcp_forward_data' callbacks for all "data"
1205  * filters attached to a stream. Returns 0 if an error occurs or if it needs to
1206  * wait, any other value otherwise.
1207  */
1208 int
flt_xfer_data(struct stream * s,struct channel * chn,unsigned int an_bit)1209 flt_xfer_data(struct stream *s, struct channel *chn, unsigned int an_bit)
1210 {
1211 	int ret = 1;
1212 
1213 	/* If there is no "data" filters, we do nothing */
1214 	if (!HAS_DATA_FILTERS(s, chn) || (s->flags & SF_HTX))
1215 		goto end;
1216 
1217 	/* Be sure that the output is still opened. Else we stop the data
1218 	 * filtering. */
1219 	if ((chn->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
1220 	    ((chn->flags & CF_SHUTW) && (chn->to_forward || co_data(chn))))
1221 		goto end;
1222 
1223 	/* Let all "data" filters parsing incoming data */
1224 	ret = flt_data(s, chn);
1225 	if (ret < 0)
1226 		goto end;
1227 
1228 	/* And forward them */
1229 	ret = flt_forward_data(s, chn, ret);
1230 	if (ret < 0)
1231 		goto end;
1232 
1233 	/* Consume data that all filters consider as forwarded. */
1234 	c_adv(chn, ret);
1235 
1236 	/* Stop waiting data if the input in closed and no data is pending or if
1237 	 * the output is closed. */
1238 	if ((chn->flags & CF_SHUTW) ||
1239 	    ((chn->flags & CF_SHUTR) && !ci_data(chn))) {
1240 		ret = 1;
1241 		goto end;
1242 	}
1243 
1244 	/* Wait for data */
1245 	return 0;
1246  end:
1247 	/* Terminate the data filtering. If <ret> is negative, an error was
1248 	 * encountered during the filtering. */
1249 	return handle_analyzer_result(s, chn, an_bit, ret);
1250 }
1251 
1252 /*
1253  * Handles result of filter's analyzers. It returns 0 if an error occurs or if
1254  * it needs to wait, any other value otherwise.
1255  */
1256 static int
handle_analyzer_result(struct stream * s,struct channel * chn,unsigned int an_bit,int ret)1257 handle_analyzer_result(struct stream *s, struct channel *chn,
1258 		       unsigned int an_bit, int ret)
1259 {
1260 	int finst;
1261 	int status = 0;
1262 
1263 	if (ret < 0)
1264 		goto return_bad_req;
1265 	else if (!ret)
1266 		goto wait;
1267 
1268 	/* End of job, return OK */
1269 	if (an_bit) {
1270 		chn->analysers  &= ~an_bit;
1271 		chn->analyse_exp = TICK_ETERNITY;
1272 	}
1273 	return 1;
1274 
1275  return_bad_req:
1276 	/* An error occurs */
1277 	channel_abort(&s->req);
1278 	channel_abort(&s->res);
1279 
1280 	if (!(chn->flags & CF_ISRESP)) {
1281 		s->req.analysers &= AN_REQ_FLT_END;
1282 		finst = SF_FINST_R;
1283 		status = 400;
1284 		/* FIXME: incr counters */
1285 	}
1286 	else {
1287 		s->res.analysers &= AN_RES_FLT_END;
1288 		finst = SF_FINST_H;
1289 		status = 502;
1290 		/* FIXME: incr counters */
1291 	}
1292 
1293 	if (s->txn) {
1294 		/* Do not do that when we are waiting for the next request */
1295 		if (s->txn->status > 0)
1296 			http_reply_and_close(s, s->txn->status, NULL);
1297 		else {
1298 			s->txn->status = status;
1299 			http_reply_and_close(s, status, http_error_message(s));
1300 		}
1301 	}
1302 
1303 	if (!(s->flags & SF_ERR_MASK))
1304 		s->flags |= SF_ERR_PRXCOND;
1305 	if (!(s->flags & SF_FINST_MASK))
1306 		s->flags |= finst;
1307 	return 0;
1308 
1309  wait:
1310 	if (!(chn->flags & CF_ISRESP))
1311 		channel_dont_connect(chn);
1312 	return 0;
1313 }
1314 
1315 
1316 /* Note: must not be declared <const> as its list will be overwritten.
1317  * Please take care of keeping this list alphabetically sorted, doing so helps
1318  * all code contributors.
1319  * Optional keywords are also declared with a NULL ->parse() function so that
1320  * the config parser can report an appropriate error when a known keyword was
1321  * not enabled. */
1322 static struct cfg_kw_list cfg_kws = {ILH, {
1323 		{ CFG_LISTEN, "filter", parse_filter },
1324 		{ 0, NULL, NULL },
1325 	}
1326 };
1327 
1328 INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
1329 
1330 REGISTER_POST_CHECK(flt_init_all);
1331 REGISTER_PER_THREAD_INIT(flt_init_all_per_thread);
1332 REGISTER_PER_THREAD_DEINIT(flt_deinit_all_per_thread);
1333 
1334 /*
1335  * Local variables:
1336  *  c-indent-level: 8
1337  *  c-basic-offset: 8
1338  * End:
1339  */
1340