/*
 * "tcp" rules processing
 *
 * Copyright 2000-2016 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */
#include <haproxy/acl.h>
#include <haproxy/action.h>
#include <haproxy/api.h>
#include <haproxy/arg-t.h>
#include <haproxy/capture-t.h>
#include <haproxy/cfgparse.h>
#include <haproxy/channel.h>
#include <haproxy/connection.h>
#include <haproxy/global.h>
#include <haproxy/list.h>
#include <haproxy/log.h>
#include <haproxy/proxy.h>
#include <haproxy/sample.h>
#include <haproxy/sc_strm.h>
#include <haproxy/stconn.h>
#include <haproxy/stick_table.h>
#include <haproxy/stream-t.h>
#include <haproxy/tcp_rules.h>
#include <haproxy/ticks.h>
#include <haproxy/tools.h>
#include <haproxy/trace.h>


#define TRACE_SOURCE &trace_strm

/* List head of all known action keywords for "tcp-request connection" */
struct list tcp_req_conn_keywords = LIST_HEAD_INIT(tcp_req_conn_keywords);
struct list tcp_req_sess_keywords = LIST_HEAD_INIT(tcp_req_sess_keywords);
struct list tcp_req_cont_keywords = LIST_HEAD_INIT(tcp_req_cont_keywords);
struct list tcp_res_cont_keywords = LIST_HEAD_INIT(tcp_res_cont_keywords);

/*
 * Register keywords.
 */
void tcp_req_conn_keywords_register(struct action_kw_list *kw_list)
{
	LIST_APPEND(&tcp_req_conn_keywords, &kw_list->list);
}

void tcp_req_sess_keywords_register(struct action_kw_list *kw_list)
{
	LIST_APPEND(&tcp_req_sess_keywords, &kw_list->list);
}

void tcp_req_cont_keywords_register(struct action_kw_list *kw_list)
{
	LIST_APPEND(&tcp_req_cont_keywords, &kw_list->list);
}

void tcp_res_cont_keywords_register(struct action_kw_list *kw_list)
{
	LIST_APPEND(&tcp_res_cont_keywords, &kw_list->list);
}

/*
 * Return the struct tcp_req_action_kw associated to a keyword.
 */
struct action_kw *tcp_req_conn_action(const char *kw)
{
	return action_lookup(&tcp_req_conn_keywords, kw);
}

struct action_kw *tcp_req_sess_action(const char *kw)
{
	return action_lookup(&tcp_req_sess_keywords, kw);
}

struct action_kw *tcp_req_cont_action(const char *kw)
{
	return action_lookup(&tcp_req_cont_keywords, kw);
}

struct action_kw *tcp_res_cont_action(const char *kw)
{
	return action_lookup(&tcp_res_cont_keywords, kw);
}

/* This function performs the TCP request analysis on the current request. It
 * returns 1 if the processing can continue on next analysers, or zero if it
 * needs more data, encounters an error, or wants to immediately abort the
 * request. It relies on buffers flags, and updates s->req->analysers. The
 * function may be called for frontend rules and backend rules. It only relies
 * on the backend pointer so this works for both cases.
 */
int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit)
{
	struct list *def_rules, *rules;
	struct session *sess = s->sess;
	struct act_rule *rule;
	int partial;
	int act_opts = 0;

	DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_TCP_ANA, s);

	def_rules = ((s->be->defpx && (an_bit == AN_REQ_INSPECT_FE || s->be->defpx != sess->fe->defpx)) ? &s->be->defpx->tcp_req.inspect_rules : NULL);
	rules = &s->be->tcp_req.inspect_rules;

	/* We don't know whether we have enough data, so must proceed
	 * this way :
	 * - iterate through all rules in their declaration order
	 * - if one rule returns MISS, it means the inspect delay is
	 *   not over yet, then return immediately, otherwise consider
	 *   it as a non-match.
	 * - if one rule returns OK, then return OK
	 * - if one rule returns KO, then return KO
	 */

	if ((req->flags & (CF_EOI|CF_SHUTR)) || channel_full(req, global.tune.maxrewrite) ||
	    sc_waiting_room(chn_prod(req)) ||
	    !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
		partial = SMP_OPT_FINAL;
		/* Action may yield while the inspect_delay is not expired and there is no read error */
		if (sc_ep_test(s->scf, SE_FL_ERROR) || !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
			act_opts |= ACT_OPT_FINAL;
	}
	else
		partial = 0;

	/* If "the current_rule_list" match the executed rule list, we are in
	 * resume condition. If a resume is needed it is always in the action
	 * and never in the ACL or converters. In this case, we initialise the
	 * current rule, and go to the action execution point.
	 */
	if (s->current_rule) {
		rule = s->current_rule;
		s->current_rule = NULL;
		if ((def_rules && s->current_rule_list == def_rules) || s->current_rule_list == rules)
			goto resume_execution;
	}
	s->current_rule_list = ((!def_rules || s->current_rule_list == def_rules) ? rules : def_rules);

  restart:
	list_for_each_entry(rule, s->current_rule_list, list) {
		enum acl_test_res ret = ACL_TEST_PASS;

		if (rule->cond) {
			ret = acl_exec_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ | partial);
			if (ret == ACL_TEST_MISS)
				goto missing_data;

			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			act_opts |= ACT_OPT_FIRST;
resume_execution:
			/* Always call the action function if defined */
			if (rule->action_ptr) {
				switch (rule->action_ptr(rule, s->be, s->sess, s, act_opts)) {
					case ACT_RET_CONT:
						break;
					case ACT_RET_STOP:
					case ACT_RET_DONE:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto end;
					case ACT_RET_YIELD:
						s->current_rule = rule;
						if (act_opts & ACT_OPT_FINAL) {
							send_log(s->be, LOG_WARNING,
								 "Internal error: yield not allowed if the inspect-delay expired "
								 "for the tcp-request content actions.");
							goto internal;
						}
						goto missing_data;
					case ACT_RET_DENY:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto deny;
					case ACT_RET_ABRT:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto abort;
					case ACT_RET_ERR:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto internal;
					case ACT_RET_INV:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto invalid;
				}
				continue; /* eval the next rule */
			}

			/* If not action function defined, check for known actions */
			if (rule->action == ACT_ACTION_ALLOW) {
				s->last_rule_file = rule->conf.file;
				s->last_rule_line = rule->conf.line;
				goto end;
			}
			else if (rule->action == ACT_ACTION_DENY) {
				s->last_rule_file = rule->conf.file;
				s->last_rule_line = rule->conf.line;
				goto deny;
			}
		}
	}

	if (def_rules && s->current_rule_list == def_rules) {
		s->current_rule_list = rules;
		goto restart;
	}

 end:
	/* if we get there, it means we have no rule which matches, or
	 * we have an explicit accept, so we apply the default accept.
	 */
	req->analysers &= ~an_bit;
	s->current_rule = s->current_rule_list = NULL;
	req->analyse_exp = s->rules_exp = TICK_ETERNITY;
	DBG_TRACE_LEAVE(STRM_EV_STRM_ANA|STRM_EV_TCP_ANA, s);
	return 1;

 missing_data:
	channel_dont_connect(req);
	/* just set the request timeout once at the beginning of the request */
	if (!tick_isset(s->rules_exp) && s->be->tcp_req.inspect_delay)
		s->rules_exp = tick_add(now_ms, s->be->tcp_req.inspect_delay);
	req->analyse_exp = tick_first((tick_is_expired(req->analyse_exp, now_ms) ? 0 : req->analyse_exp), s->rules_exp);
	DBG_TRACE_DEVEL("waiting for more data", STRM_EV_STRM_ANA|STRM_EV_TCP_ANA, s);
	return 0;

 deny:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->denied_req);
	goto reject;

 internal:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_INTERNAL;
	goto reject;

 invalid:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->failed_req);

 reject:
	sc_must_kill_conn(chn_prod(req));
	channel_abort(req);
	channel_abort(&s->res);

 abort:
	req->analysers &= AN_REQ_FLT_END;
	s->current_rule = s->current_rule_list = NULL;
	req->analyse_exp = s->rules_exp = TICK_ETERNITY;

	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_PRXCOND;
	if (!(s->flags & SF_FINST_MASK))
		s->flags |= SF_FINST_R;
	DBG_TRACE_DEVEL("leaving on error|deny|abort", STRM_EV_STRM_ANA|STRM_EV_TCP_ANA|STRM_EV_TCP_ERR, s);
	return 0;
}

/* This function performs the TCP response analysis on the current response. It
 * returns 1 if the processing can continue on next analysers, or zero if it
 * needs more data, encounters an error, or wants to immediately abort the
 * response. It relies on buffers flags, and updates s->rep->analysers. The
 * function may be called for backend rules.
 */
int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit)
{
	struct list *def_rules, *rules;
	struct session *sess = s->sess;
	struct act_rule *rule;
	int partial;
	int act_opts = 0;

	DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_TCP_ANA, s);

	def_rules = (s->be->defpx ? &s->be->defpx->tcp_rep.inspect_rules : NULL);
	rules = &s->be->tcp_rep.inspect_rules;

	/* We don't know whether we have enough data, so must proceed
	 * this way :
	 * - iterate through all rules in their declaration order
	 * - if one rule returns MISS, it means the inspect delay is
	 *   not over yet, then return immediately, otherwise consider
	 *   it as a non-match.
	 * - if one rule returns OK, then return OK
	 * - if one rule returns KO, then return KO
	 */
	if ((rep->flags & (CF_EOI|CF_SHUTR)) || channel_full(rep, global.tune.maxrewrite) ||
	    sc_waiting_room(chn_prod(rep)) ||
	    !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
		partial = SMP_OPT_FINAL;
		/* Action may yield while the inspect_delay is not expired and there is no read error */
		if (sc_ep_test(s->scb, SE_FL_ERROR) || !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
			act_opts |= ACT_OPT_FINAL;
	}
	else
		partial = 0;

	/* If "the current_rule_list" match the executed rule list, we are in
	 * resume condition. If a resume is needed it is always in the action
	 * and never in the ACL or converters. In this case, we initialise the
	 * current rule, and go to the action execution point.
	 */
	if (s->current_rule) {
		rule = s->current_rule;
		s->current_rule = NULL;
		if ((def_rules && s->current_rule_list == def_rules) || s->current_rule_list == rules)
			goto resume_execution;
	}
	s->current_rule_list = ((!def_rules || s->current_rule_list == def_rules) ? rules : def_rules);

  restart:
	list_for_each_entry(rule, s->current_rule_list, list) {
		enum acl_test_res ret = ACL_TEST_PASS;

		if (rule->cond) {
			ret = acl_exec_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_RES | partial);
			if (ret == ACL_TEST_MISS)
				goto missing_data;

			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			act_opts |= ACT_OPT_FIRST;
resume_execution:
			/* Always call the action function if defined */
			if (rule->action_ptr) {
				switch (rule->action_ptr(rule, s->be, s->sess, s, act_opts)) {
					case ACT_RET_CONT:
						break;
					case ACT_RET_STOP:
					case ACT_RET_DONE:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto end;
					case ACT_RET_YIELD:
						s->current_rule = rule;
						if (act_opts & ACT_OPT_FINAL) {
							send_log(s->be, LOG_WARNING,
								 "Internal error: yield not allowed if the inspect-delay expired "
								 "for the tcp-response content actions.");
							goto internal;
						}
						channel_dont_close(rep);
						goto missing_data;
					case ACT_RET_DENY:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto deny;
					case ACT_RET_ABRT:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto abort;
					case ACT_RET_ERR:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto internal;
					case ACT_RET_INV:
						s->last_rule_file = rule->conf.file;
						s->last_rule_line = rule->conf.line;
						goto invalid;
				}
				continue; /* eval the next rule */
			}

			/* If not action function defined, check for known actions */
			if (rule->action == ACT_ACTION_ALLOW) {
				s->last_rule_file = rule->conf.file;
				s->last_rule_line = rule->conf.line;
				goto end;
			}
			else if (rule->action == ACT_ACTION_DENY) {
				s->last_rule_file = rule->conf.file;
				s->last_rule_line = rule->conf.line;
				goto deny;
			}
			else if (rule->action == ACT_TCP_CLOSE) {
				chn_prod(rep)->flags |= SC_FL_NOLINGER | SC_FL_NOHALF;
				sc_must_kill_conn(chn_prod(rep));
				sc_shutr(chn_prod(rep));
				sc_shutw(chn_prod(rep));
				s->last_rule_file = rule->conf.file;
				s->last_rule_line = rule->conf.line;
				goto end;
			}
		}
	}

	if (def_rules && s->current_rule_list == def_rules) {
		s->current_rule_list = rules;
		goto restart;
	}

 end:
	/* if we get there, it means we have no rule which matches, or
	 * we have an explicit accept, so we apply the default accept.
	 */
	rep->analysers &= ~an_bit;
	s->current_rule = s->current_rule_list = NULL;
	rep->analyse_exp = s->rules_exp = TICK_ETERNITY;
	DBG_TRACE_LEAVE(STRM_EV_STRM_ANA|STRM_EV_TCP_ANA, s);
	return 1;

 missing_data:
	/* just set the analyser timeout once at the beginning of the response */
	if (!tick_isset(s->rules_exp) && s->be->tcp_rep.inspect_delay)
		s->rules_exp = tick_add(now_ms, s->be->tcp_rep.inspect_delay);
	rep->analyse_exp = tick_first((tick_is_expired(rep->analyse_exp, now_ms) ? 0 : rep->analyse_exp), s->rules_exp);
	DBG_TRACE_DEVEL("waiting for more data", STRM_EV_STRM_ANA|STRM_EV_TCP_ANA, s);
	return 0;

  deny:
	_HA_ATOMIC_INC(&s->sess->fe->fe_counters.denied_resp);
	_HA_ATOMIC_INC(&s->be->be_counters.denied_resp);
	if (s->sess->listener && s->sess->listener->counters)
		_HA_ATOMIC_INC(&s->sess->listener->counters->denied_resp);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.denied_resp);
	goto reject;

 internal:
	_HA_ATOMIC_INC(&s->sess->fe->fe_counters.internal_errors);
	_HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
	if (s->sess->listener && s->sess->listener->counters)
		_HA_ATOMIC_INC(&s->sess->listener->counters->internal_errors);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_INTERNAL;
	goto reject;

 invalid:
	_HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);

 reject:
	sc_must_kill_conn(chn_prod(rep));
	channel_abort(rep);
	channel_abort(&s->req);

  abort:
	rep->analysers &= AN_RES_FLT_END;
	s->current_rule = s->current_rule_list = NULL;
	rep->analyse_exp = s->rules_exp = TICK_ETERNITY;

	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_PRXCOND;
	if (!(s->flags & SF_FINST_MASK))
		s->flags |= SF_FINST_D;
	DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_ANA|STRM_EV_TCP_ANA|STRM_EV_TCP_ERR, s);
	return 0;
}


/* This function performs the TCP layer4 analysis on the current request. It
 * returns 0 if a reject rule matches, otherwise 1 if either an accept rule
 * matches or if no more rule matches. It can only use rules which don't need
 * any data. This only works on connection-based client-facing stream connectors.
 */
int tcp_exec_l4_rules(struct session *sess)
{
	struct proxy *px = sess->fe;
	struct act_rule *rule;
	struct connection *conn = objt_conn(sess->origin);
	int result = 1;
	enum acl_test_res ret;

	if (!conn)
		return result;

	if  (sess->fe->defpx)
		px = sess->fe->defpx;

  restart:
	list_for_each_entry(rule, &px->tcp_req.l4_rules, list) {
		ret = ACL_TEST_PASS;

		if (rule->cond) {
			ret = acl_exec_cond(rule->cond, sess->fe, sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			/* Always call the action function if defined */
			if (rule->action_ptr) {
				switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_OPT_FINAL | ACT_OPT_FIRST)) {
					case ACT_RET_YIELD:
						/* yield is not allowed at this point. If this return code is
						 * used it is a bug, so I prefer to abort the process.
						 */
						send_log(sess->fe, LOG_WARNING,
							 "Internal error: yield not allowed with tcp-request connection actions.");
						/* fall through */
					case ACT_RET_STOP:
					case ACT_RET_DONE:
						goto end;
					case ACT_RET_CONT:
						break;
					case ACT_RET_DENY:
					case ACT_RET_ABRT:
					case ACT_RET_ERR:
					case ACT_RET_INV:
						result = 0;
						goto end;
				}
				continue; /* eval the next rule */
			}

			/* If not action function defined, check for known actions */
			if (rule->action == ACT_ACTION_ALLOW) {
				goto end;
			}
			else if (rule->action == ACT_ACTION_DENY) {
				_HA_ATOMIC_INC(&sess->fe->fe_counters.denied_conn);
				if (sess->listener && sess->listener->counters)
					_HA_ATOMIC_INC(&sess->listener->counters->denied_conn);

				result = 0;
				goto end;
			}
			else if (rule->action == ACT_TCP_EXPECT_PX) {
				if (!(conn->flags & CO_FL_HANDSHAKE)) {
					if (xprt_add_hs(conn) < 0) {
						result = 0;
						goto end;
					}
				}
				conn->flags |= CO_FL_ACCEPT_PROXY;
			}
			else if (rule->action == ACT_TCP_EXPECT_CIP) {
				if (!(conn->flags & CO_FL_HANDSHAKE)) {
					if (xprt_add_hs(conn) < 0) {
						result = 0;
						goto end;
					}
				}
				conn->flags |= CO_FL_ACCEPT_CIP;
			}
		}
	}

	if (px != sess->fe) {
		px = sess->fe;
		goto restart;
	}
 end:
	return result;
}

/* This function performs the TCP layer5 analysis on the current request. It
 * returns 0 if a reject rule matches, otherwise 1 if either an accept rule
 * matches or if no more rule matches. It can only use rules which don't need
 * any data. This only works on session-based client-facing stream connectors.
 * An example of valid use case is to track a stick-counter on the source
 * address extracted from the proxy protocol.
 */
int tcp_exec_l5_rules(struct session *sess)
{
	struct proxy *px = sess->fe;
	struct act_rule *rule;
	int result = 1;
	enum acl_test_res ret;

	if  (sess->fe->defpx)
		px = sess->fe->defpx;

  restart:
	list_for_each_entry(rule, &px->tcp_req.l5_rules, list) {
		ret = ACL_TEST_PASS;

		if (rule->cond) {
			ret = acl_exec_cond(rule->cond, sess->fe, sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			/* Always call the action function if defined */
			if (rule->action_ptr) {
				switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_OPT_FINAL | ACT_OPT_FIRST)) {
					case ACT_RET_YIELD:
						/* yield is not allowed at this point. If this return code is
						 * used it is a bug, so I prefer to abort the process.
						 */
						send_log(sess->fe, LOG_WARNING,
							 "Internal error: yield not allowed with tcp-request session actions.");
						/* fall through */
					case ACT_RET_STOP:
					case ACT_RET_DONE:
						goto end;
					case ACT_RET_CONT:
						break;
					case ACT_RET_DENY:
					case ACT_RET_ABRT:
					case ACT_RET_ERR:
					case ACT_RET_INV:
						result = 0;
						goto end;
				}
				continue; /* eval the next rule */
			}

			/* If not action function defined, check for known actions */
			if (rule->action == ACT_ACTION_ALLOW) {
				goto end;
			}
			else if (rule->action == ACT_ACTION_DENY) {
				_HA_ATOMIC_INC(&sess->fe->fe_counters.denied_sess);
				if (sess->listener && sess->listener->counters)
					_HA_ATOMIC_INC(&sess->listener->counters->denied_sess);

				result = 0;
				goto end;
			}
		}
	}

	if (px != sess->fe) {
		px = sess->fe;
		goto restart;
	}
  end:
	return result;
}

/* Parse a tcp-response rule. Return a negative value in case of failure */
static int tcp_parse_response_rule(char **args, int arg, int section_type,
                                   struct proxy *curpx, const struct proxy *defpx,
                                   struct act_rule *rule, char **err,
                                   unsigned int where,
                                   const char *file, int line)
{
	if ((curpx == defpx && strlen(defpx->id) == 0) || !(curpx->cap & PR_CAP_BE)) {
		memprintf(err, "%s %s is only allowed in 'backend' sections or 'defaults' section with a name",
		          args[0], args[1]);
		return -1;
	}

	if (strcmp(args[arg], "accept") == 0) {
		arg++;
		rule->action = ACT_ACTION_ALLOW;
		rule->flags |= ACT_FLAG_FINAL;
	}
	else if (strcmp(args[arg], "reject") == 0) {
		arg++;
		rule->action = ACT_ACTION_DENY;
		rule->flags |= ACT_FLAG_FINAL;
	}
	else if (strcmp(args[arg], "close") == 0) {
		arg++;
		rule->action = ACT_TCP_CLOSE;
		rule->flags |= ACT_FLAG_FINAL;
	}
	else {
		struct action_kw *kw;
		kw = tcp_res_cont_action(args[arg]);
		if (kw) {
			arg++;
			rule->kw = kw;
			if (kw->parse((const char **)args, &arg, curpx, rule, err) == ACT_RET_PRS_ERR)
				return -1;
		} else {
			const char *extra[] = { "accept", "reject", "close", NULL };
			const char *best = action_suggest(args[arg], &tcp_res_cont_keywords, extra);

			action_build_list(&tcp_res_cont_keywords, &trash);
			memprintf(err,
			          "'%s %s' expects 'accept', 'close', 'reject', %s in %s '%s' (got '%s').%s%s%s",
			          args[0], args[1], trash.area,
			          proxy_type_str(curpx), curpx->id, args[arg],
			          best ? " Did you mean '" : "",
			          best ? best : "",
			          best ? "' maybe ?" : "");
			return -1;
		}
	}

	if (strcmp(args[arg], "if") == 0 || strcmp(args[arg], "unless") == 0) {
		if ((rule->cond = build_acl_cond(file, line, &curpx->acl, curpx, (const char **)args+arg, err)) == NULL) {
			memprintf(err,
			          "'%s %s %s' : error detected in %s '%s' while parsing '%s' condition : %s",
			          args[0], args[1], args[2], proxy_type_str(curpx), curpx->id, args[arg], *err);
			return -1;
		}
	}
	else if (*args[arg]) {
		memprintf(err,
			 "'%s %s %s' only accepts 'if' or 'unless', in %s '%s' (got '%s')",
			 args[0], args[1], args[2], proxy_type_str(curpx), curpx->id, args[arg]);
		return -1;
	}
	return 0;
}


/* This function executes a track-sc* actions. On success, it returns
 * ACT_RET_CONT. If it must yield, it return ACT_RET_YIELD. Otherwsize
 * ACT_RET_ERR is returned.
 */
static enum act_return tcp_action_track_sc(struct act_rule *rule, struct proxy *px,
					    struct session *sess, struct stream *s, int flags)
{
	struct stksess *ts;
	struct stktable *t;
	struct stktable_key *key;
	struct sample smp;
	int opt;

	opt = SMP_OPT_DIR_REQ;
	if (flags & ACT_FLAG_FINAL)
		opt |= SMP_OPT_FINAL;

	t = rule->arg.trk_ctr.table.t;
	if (rule->from == ACT_F_TCP_REQ_CNT) { /* L7 rules: use the stream */
		if (stkctr_entry(&s->stkctr[rule->action]))
			goto end;

		key = stktable_fetch_key(t, s->be, sess, s, opt, rule->arg.trk_ctr.expr, &smp);

		if ((smp.flags & SMP_F_MAY_CHANGE) && !(flags & ACT_FLAG_FINAL))
			return ACT_RET_YIELD; /* key might appear later */

		if (key && (ts = stktable_get_entry(t, key))) {
			stream_track_stkctr(&s->stkctr[rule->action], t, ts);
			stkctr_set_flags(&s->stkctr[rule->action], STKCTR_TRACK_CONTENT);
			if (sess->fe != s->be)
				stkctr_set_flags(&s->stkctr[rule->action], STKCTR_TRACK_BACKEND);
		}
	}
	else {  /* L4/L5 rules: use the session */
		if (stkctr_entry(&sess->stkctr[rule->action]))
			goto end;

		key = stktable_fetch_key(t, sess->fe, sess, NULL, opt, rule->arg.trk_ctr.expr, NULL);
		if (key && (ts = stktable_get_entry(t, key)))
			stream_track_stkctr(&sess->stkctr[rule->action], t, ts);
	}

  end:
	return ACT_RET_CONT;
}

/* This function executes a capture actions. It executes a fetch expression,
 * turns the result into a string and puts it in a capture slot. On success, it
 * returns ACT_RET_CONT. If it must yield, it return ACT_RET_YIELD. Otherwsize
 * ACT_RET_ERR is returned.
 */
static enum act_return tcp_action_capture(struct act_rule *rule, struct proxy *px,
					  struct session *sess, struct stream *s, int flags)
{
	struct sample *key;
	struct cap_hdr *h = rule->arg.cap.hdr;
	char **cap = s->req_cap;
	int len, opt;

	opt = ((rule->from == ACT_F_TCP_REQ_CNT) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES);
	if (flags & ACT_FLAG_FINAL)
		opt |= SMP_OPT_FINAL;

	key = sample_fetch_as_type(s->be, sess, s, opt, rule->arg.cap.expr, SMP_T_STR);
	if (!key)
		goto end;

	if ((key->flags & SMP_F_MAY_CHANGE) && !(flags & ACT_FLAG_FINAL))
		return ACT_RET_YIELD; /* key might appear later */

	if (cap[h->index] == NULL) {
		cap[h->index] = pool_alloc(h->pool);
		if (cap[h->index] == NULL) /* no more capture memory, ignore error */
			goto end;
	}

	len = key->data.u.str.data;
	if (len > h->len)
		len = h->len;

	memcpy(cap[h->index], key->data.u.str.area, len);
	cap[h->index][len] = 0;

  end:
	return ACT_RET_CONT;
}

static void release_tcp_capture(struct act_rule * rule)
{
	release_sample_expr(rule->arg.cap.expr);
}


static void release_tcp_track_sc(struct act_rule * rule)
{
	release_sample_expr(rule->arg.trk_ctr.expr);
}

/* Parse a tcp-request rule. Return a negative value in case of failure */
static int tcp_parse_request_rule(char **args, int arg, int section_type,
                                  struct proxy *curpx, const struct proxy *defpx,
                                  struct act_rule *rule, char **err,
                                  unsigned int where, const char *file, int line)
{
	if (curpx == defpx && strlen(defpx->id) == 0) {
		memprintf(err, "%s %s is not allowed in anonymous 'defaults' sections",
			  args[0], args[1]);
		return -1;
	}

	if (strcmp(args[arg], "accept") == 0) {
		arg++;
		rule->action = ACT_ACTION_ALLOW;
		rule->flags |= ACT_FLAG_FINAL;
	}
	else if (strcmp(args[arg], "reject") == 0) {
		arg++;
		rule->action = ACT_ACTION_DENY;
		rule->flags |= ACT_FLAG_FINAL;
	}
	else if (strcmp(args[arg], "capture") == 0) {
		struct sample_expr *expr;
		struct cap_hdr *hdr;
		int kw = arg;
		int len = 0;

		if (!(curpx->cap & PR_CAP_FE)) {
			memprintf(err,
			          "'%s %s %s' : proxy '%s' has no frontend capability",
			          args[0], args[1], args[kw], curpx->id);
			return -1;
		}

		if (!(where & SMP_VAL_FE_REQ_CNT)) {
			memprintf(err,
				  "'%s %s' is not allowed in '%s %s' rules in %s '%s'",
				  args[arg], args[arg+1], args[0], args[1], proxy_type_str(curpx), curpx->id);
			return -1;
		}

		arg++;

		curpx->conf.args.ctx = ARGC_CAP;
		expr = sample_parse_expr(args, &arg, file, line, err, &curpx->conf.args, NULL);
		if (!expr) {
			memprintf(err,
			          "'%s %s %s' : %s",
			          args[0], args[1], args[kw], *err);
			return -1;
		}

		if (!(expr->fetch->val & where)) {
			memprintf(err,
			          "'%s %s %s' : fetch method '%s' extracts information from '%s', none of which is available here",
			          args[0], args[1], args[kw], args[arg-1], sample_src_names(expr->fetch->use));
			release_sample_expr(expr);
			return -1;
		}

		if (strcmp(args[arg], "len") == 0) {
			arg++;
			if (!args[arg]) {
				memprintf(err,
					  "'%s %s %s' : missing length value",
					  args[0], args[1], args[kw]);
				release_sample_expr(expr);
				return -1;
			}
			/* we copy the table name for now, it will be resolved later */
			len = atoi(args[arg]);
			if (len <= 0) {
				memprintf(err,
					  "'%s %s %s' : length must be > 0",
					  args[0], args[1], args[kw]);
				release_sample_expr(expr);
				return -1;
			}
			arg++;
		}

		if (!len) {
			memprintf(err,
				  "'%s %s %s' : a positive 'len' argument is mandatory",
				  args[0], args[1], args[kw]);
			free(expr);
			return -1;
		}

		hdr = calloc(1, sizeof(*hdr));
		if (!hdr) {
			memprintf(err, "parsing [%s:%d] : out of memory", file, line);
			release_sample_expr(expr);
			return -1;
		}
		hdr->next = curpx->req_cap;
		hdr->name = NULL; /* not a header capture */
		hdr->namelen = 0;
		hdr->len = len;
		hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
		hdr->index = curpx->nb_req_cap++;

		curpx->req_cap = hdr;
		curpx->to_log |= LW_REQHDR;

		/* check if we need to allocate an http_txn struct for HTTP parsing */
		curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);

		rule->arg.cap.expr = expr;
		rule->arg.cap.hdr = hdr;
		rule->action = ACT_CUSTOM;
		rule->action_ptr = tcp_action_capture;
		rule->check_ptr = check_capture;
		rule->release_ptr  = release_tcp_capture;
	}
	else if (strncmp(args[arg], "track-sc", 8) == 0) {
		struct sample_expr *expr;
		int kw = arg;
		unsigned int tsc_num;
		const char *tsc_num_str;

		arg++;

		tsc_num_str = &args[kw][8];
		if (cfg_parse_track_sc_num(&tsc_num, tsc_num_str, tsc_num_str + strlen(tsc_num_str), err) == -1) {
			memprintf(err, "'%s %s %s' : %s", args[0], args[1], args[kw], *err);
			return -1;
		}

		curpx->conf.args.ctx = ARGC_TRK;
		expr = sample_parse_expr(args, &arg, file, line, err, &curpx->conf.args, NULL);
		if (!expr) {
			memprintf(err,
			          "'%s %s %s' : %s",
			          args[0], args[1], args[kw], *err);
			return -1;
		}

		if (!(expr->fetch->val & where)) {
			memprintf(err,
			          "'%s %s %s' : fetch method '%s' extracts information from '%s', none of which is available here",
			          args[0], args[1], args[kw], args[arg-1], sample_src_names(expr->fetch->use));
			release_sample_expr(expr);
			return -1;
		}

		/* check if we need to allocate an http_txn struct for HTTP parsing */
		curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);

		if (strcmp(args[arg], "table") == 0) {
			arg++;
			if (!args[arg]) {
				memprintf(err,
					  "'%s %s %s' : missing table name",
					  args[0], args[1], args[kw]);
				release_sample_expr(expr);
				return -1;
			}
			/* we copy the table name for now, it will be resolved later */
			rule->arg.trk_ctr.table.n = strdup(args[arg]);
			arg++;
		}
		rule->action = tsc_num;
		rule->arg.trk_ctr.expr = expr;
		rule->action_ptr = tcp_action_track_sc;
		rule->check_ptr = check_trk_action;
		rule->release_ptr  = release_tcp_track_sc;
	}
	else if (strcmp(args[arg], "expect-proxy") == 0) {
		if (strcmp(args[arg+1], "layer4") != 0) {
			memprintf(err,
				  "'%s %s %s' only supports 'layer4' in %s '%s' (got '%s')",
				  args[0], args[1], args[arg], proxy_type_str(curpx), curpx->id, args[arg+1]);
			return -1;
		}

		if (!(where & SMP_VAL_FE_CON_ACC)) {
			memprintf(err,
				  "'%s %s' is not allowed in '%s %s' rules in %s '%s'",
				  args[arg], args[arg+1], args[0], args[1], proxy_type_str(curpx), curpx->id);
			return -1;
		}

		arg += 2;
		rule->action = ACT_TCP_EXPECT_PX;
	}
	else if (strcmp(args[arg], "expect-netscaler-cip") == 0) {
		if (strcmp(args[arg+1], "layer4") != 0) {
			memprintf(err,
				  "'%s %s %s' only supports 'layer4' in %s '%s' (got '%s')",
				  args[0], args[1], args[arg], proxy_type_str(curpx), curpx->id, args[arg+1]);
			return -1;
		}

		if (!(where & SMP_VAL_FE_CON_ACC)) {
			memprintf(err,
				  "'%s %s' is not allowed in '%s %s' rules in %s '%s'",
				  args[arg], args[arg+1], args[0], args[1], proxy_type_str(curpx), curpx->id);
			return -1;
		}

		arg += 2;
		rule->action = ACT_TCP_EXPECT_CIP;
	}
	else {
		struct action_kw *kw;
		if (where & SMP_VAL_FE_CON_ACC) {
			/* L4 */
			kw = tcp_req_conn_action(args[arg]);
			rule->kw = kw;
		} else if (where & SMP_VAL_FE_SES_ACC) {
			/* L5 */
			kw = tcp_req_sess_action(args[arg]);
			rule->kw = kw;
		} else {
			/* L6 */
			kw = tcp_req_cont_action(args[arg]);
			rule->kw = kw;
		}
		if (kw) {
			arg++;
			if (kw->parse((const char **)args, &arg, curpx, rule, err) == ACT_RET_PRS_ERR)
				return -1;
		} else {
			const char *extra[] = { "accept", "reject", "capture", "track-sc", "expect-proxy", "expect-netscaler-cip", NULL };
			const char *best = NULL;


			if (where & SMP_VAL_FE_CON_ACC) {
				action_build_list(&tcp_req_conn_keywords, &trash);
				best = action_suggest(args[arg], &tcp_req_conn_keywords, extra);
			}
			else if (where & SMP_VAL_FE_SES_ACC) {
				action_build_list(&tcp_req_sess_keywords, &trash);
				best = action_suggest(args[arg], &tcp_req_sess_keywords, extra);
			}
			else {
				action_build_list(&tcp_req_cont_keywords, &trash);
				best = action_suggest(args[arg], &tcp_req_cont_keywords, extra);
			}

			memprintf(err,
			          "'%s %s' expects 'accept', 'reject', 'capture', 'expect-proxy', 'expect-netscaler-cip', 'track-sc0' ... 'track-sc%d', %s "
			          "in %s '%s' (got '%s').%s%s%s\n",
			          args[0], args[1], global.tune.nb_stk_ctr-1,
			          trash.area, proxy_type_str(curpx),
			          curpx->id, args[arg],
			          best ? " Did you mean '" : "",
			          best ? best : "",
			          best ? "' maybe ?" : "");
			return -1;
		}
	}

	if (strcmp(args[arg], "if") == 0 || strcmp(args[arg], "unless") == 0) {
		if ((rule->cond = build_acl_cond(file, line, &curpx->acl, curpx, (const char **)args+arg, err)) == NULL) {
			memprintf(err,
			          "'%s %s %s' : error detected in %s '%s' while parsing '%s' condition : %s",
			          args[0], args[1], args[2], proxy_type_str(curpx), curpx->id, args[arg], *err);
			return -1;
		}
	}
	else if (*args[arg]) {
		memprintf(err,
			 "'%s %s %s' only accepts 'if' or 'unless', in %s '%s' (got '%s')",
			 args[0], args[1], args[2], proxy_type_str(curpx), curpx->id, args[arg]);
		return -1;
	}
	return 0;
}

/* This function should be called to parse a line starting with the "tcp-response"
 * keyword.
 */
static int tcp_parse_tcp_rep(char **args, int section_type, struct proxy *curpx,
                             const struct proxy *defpx, const char *file, int line,
                             char **err)
{
	const char *ptr = NULL;
	unsigned int val;
	int warn = 0;
	int arg;
	struct act_rule *rule;
	unsigned int where;
	const struct acl *acl;
	const char *kw;

	if (!*args[1]) {
		memprintf(err, "missing argument for '%s' in %s '%s'",
		          args[0], proxy_type_str(curpx), curpx->id);
		return -1;
	}

	if (strcmp(args[1], "inspect-delay") == 0) {
		if ((curpx == defpx && strlen(defpx->id) == 0) || !(curpx->cap & PR_CAP_BE)) {
			memprintf(err, "%s %s is only allowed in 'backend' sections or 'defaults' section with a name",
			          args[0], args[1]);
			return -1;
		}

		if (!*args[2] || (ptr = parse_time_err(args[2], &val, TIME_UNIT_MS))) {
			memprintf(err,
			          "'%s %s' expects a positive delay in milliseconds, in %s '%s'",
			          args[0], args[1], proxy_type_str(curpx), curpx->id);

			if (ptr == PARSE_TIME_OVER)
				memprintf(err, "%s (timer overflow in '%s', maximum value is 2147483647 ms or ~24.8 days)", *err, args[2]);
			else if (ptr == PARSE_TIME_UNDER)
				memprintf(err, "%s (timer underflow in '%s', minimum non-null value is 1 ms)", *err, args[2]);
			else if (ptr)
				memprintf(err, "%s (unexpected character '%c')", *err, *ptr);
			return -1;
		}

		if (curpx->tcp_rep.inspect_delay) {
			memprintf(err, "ignoring %s %s (was already defined) in %s '%s'",
			          args[0], args[1], proxy_type_str(curpx), curpx->id);
			return 1;
		}
		curpx->tcp_rep.inspect_delay = val;
		return 0;
	}

	rule = new_act_rule(ACT_F_TCP_RES_CNT, file, line);
	if (!rule) {
		memprintf(err, "parsing [%s:%d] : out of memory", file, line);
		return -1;
	}
	LIST_INIT(&rule->list);
	arg = 1;
	where = 0;

	if (strcmp(args[1], "content") == 0) {
		arg++;

		if (curpx->cap & PR_CAP_FE)
			where |= SMP_VAL_FE_RES_CNT;
		if (curpx->cap & PR_CAP_BE)
			where |= SMP_VAL_BE_RES_CNT;
		if (tcp_parse_response_rule(args, arg, section_type, curpx, defpx, rule, err, where, file, line) < 0)
			goto error;

		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
		if (acl) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
					  acl->name, args[0], args[1], sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
					  args[0], args[1],
					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
					  sample_ckp_names(where));

			warn++;
		}
		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
					  acl->name, kw, sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
					  kw, sample_ckp_names(where));
			warn++;
		}

		LIST_APPEND(&curpx->tcp_rep.inspect_rules, &rule->list);
	}
	else {
		memprintf(err,
		          "'%s' expects 'inspect-delay' or 'content' in %s '%s' (got '%s')",
		          args[0], proxy_type_str(curpx), curpx->id, args[1]);
		goto error;
	}

	return warn;
 error:
	free_act_rule(rule);
	return -1;
}


/* This function should be called to parse a line starting with the "tcp-request"
 * keyword.
 */
static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
                             const struct proxy *defpx, const char *file, int line,
                             char **err)
{
	const char *ptr = NULL;
	unsigned int val;
	int warn = 0;
	int arg;
	struct act_rule *rule;
	unsigned int where;
	const struct acl *acl;
	const char *kw;

	if (!*args[1]) {
		if (curpx == defpx)
			memprintf(err, "missing argument for '%s' in defaults section", args[0]);
		else
			memprintf(err, "missing argument for '%s' in %s '%s'",
			          args[0], proxy_type_str(curpx), curpx->id);
		return -1;
	}

	if (strcmp(args[1], "inspect-delay") == 0) {
		if (curpx == defpx && strlen(defpx->id) == 0) {
			memprintf(err, "%s %s is not allowed in anonymous 'defaults' sections",
				  args[0], args[1]);
			return -1;
		}

		if (!*args[2] || (ptr = parse_time_err(args[2], &val, TIME_UNIT_MS))) {
			memprintf(err,
			          "'%s %s' expects a positive delay in milliseconds, in %s '%s'",
			          args[0], args[1], proxy_type_str(curpx), curpx->id);

			if (ptr == PARSE_TIME_OVER)
				memprintf(err, "%s (timer overflow in '%s', maximum value is 2147483647 ms or ~24.8 days)", *err, args[2]);
			else if (ptr == PARSE_TIME_UNDER)
				memprintf(err, "%s (timer underflow in '%s', minimum non-null value is 1 ms)", *err, args[2]);
			else if (ptr)
				memprintf(err, "%s (unexpected character '%c')", *err, *ptr);
			return -1;
		}

		if (curpx->tcp_req.inspect_delay) {
			memprintf(err, "ignoring %s %s (was already defined) in %s '%s'",
			          args[0], args[1], proxy_type_str(curpx), curpx->id);
			return 1;
		}
		curpx->tcp_req.inspect_delay = val;
		return 0;
	}

	rule = new_act_rule(0, file, line);
	if (!rule) {
		memprintf(err, "parsing [%s:%d] : out of memory", file, line);
		return -1;
	}
	LIST_INIT(&rule->list);
	arg = 1;
	where = 0;

	if (strcmp(args[1], "content") == 0) {
		arg++;

		if (curpx->cap & PR_CAP_FE)
			where |= SMP_VAL_FE_REQ_CNT;
		if (curpx->cap & PR_CAP_BE)
			where |= SMP_VAL_BE_REQ_CNT;
		rule->from = ACT_F_TCP_REQ_CNT;
		if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where, file, line) < 0)
			goto error;

		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
		if (acl) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
					  acl->name, args[0], args[1], sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
					  args[0], args[1],
					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
					  sample_ckp_names(where));

			warn++;
		}
		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
					  acl->name, kw, sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
					  kw, sample_ckp_names(where));
			warn++;
		}

		/* the following function directly emits the warning */
		warnif_misplaced_tcp_cont(curpx, file, line, args[0]);
		LIST_APPEND(&curpx->tcp_req.inspect_rules, &rule->list);
	}
	else if (strcmp(args[1], "connection") == 0) {
		arg++;

		if (!(curpx->cap & PR_CAP_FE)) {
			memprintf(err, "%s %s is not allowed because %s %s is not a frontend",
			          args[0], args[1], proxy_type_str(curpx), curpx->id);
			goto error;
		}

		where |= SMP_VAL_FE_CON_ACC;
		rule->from = ACT_F_TCP_REQ_CON;
		if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where, file, line) < 0)
			goto error;

		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
		if (acl) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
					  acl->name, args[0], args[1], sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
					  args[0], args[1],
					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
					  sample_ckp_names(where));

			warn++;
		}
		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
					  acl->name, kw, sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
					  kw, sample_ckp_names(where));
			warn++;
		}

		/* the following function directly emits the warning */
		warnif_misplaced_tcp_conn(curpx, file, line, args[0]);
		LIST_APPEND(&curpx->tcp_req.l4_rules, &rule->list);
	}
	else if (strcmp(args[1], "session") == 0) {
		arg++;

		if (!(curpx->cap & PR_CAP_FE)) {
			memprintf(err, "%s %s is not allowed because %s %s is not a frontend",
			          args[0], args[1], proxy_type_str(curpx), curpx->id);
			goto error;
		}

		where |= SMP_VAL_FE_SES_ACC;
		rule->from = ACT_F_TCP_REQ_SES;
		if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where, file, line) < 0)
			goto error;

		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
		if (acl) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
					  acl->name, args[0], args[1], sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
					  args[0], args[1],
					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
					  sample_ckp_names(where));
			warn++;
		}
		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
			if (acl->name && *acl->name)
				memprintf(err,
					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
					  acl->name, kw, sample_ckp_names(where));
			else
				memprintf(err,
					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
					  kw, sample_ckp_names(where));
			warn++;
		}

		/* the following function directly emits the warning */
		warnif_misplaced_tcp_sess(curpx, file, line, args[0]);
		LIST_APPEND(&curpx->tcp_req.l5_rules, &rule->list);
	}
	else {
		if (curpx == defpx)
			memprintf(err,
			          "'%s' expects 'inspect-delay', 'connection', or 'content' in defaults section (got '%s')",
			          args[0], args[1]);
		else
			memprintf(err,
			          "'%s' expects 'inspect-delay', 'connection', or 'content' in %s '%s' (got '%s')",
			          args[0], proxy_type_str(curpx), curpx->id, args[1]);
		goto error;
	}

	return warn;
 error:
	free_act_rule(rule);
	return -1;
}

static struct cfg_kw_list cfg_kws = {ILH, {
	{ CFG_LISTEN, "tcp-request",  tcp_parse_tcp_req },
	{ CFG_LISTEN, "tcp-response", tcp_parse_tcp_rep },
	{ 0, NULL, NULL },
}};

INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
