/*
 * Session management functions.
 *
 * Copyright 2000-2012 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 <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#include <common/config.h>
#include <common/buffer.h>
#include <common/debug.h>
#include <common/memory.h>

#include <types/capture.h>
#include <types/global.h>

#include <proto/acl.h>
#include <proto/arg.h>
#include <proto/backend.h>
#include <proto/channel.h>
#include <proto/checks.h>
#include <proto/connection.h>
#include <proto/dumpstats.h>
#include <proto/fd.h>
#include <proto/freq_ctr.h>
#include <proto/frontend.h>
#include <proto/hdr_idx.h>
#include <proto/listener.h>
#include <proto/log.h>
#include <proto/raw_sock.h>
#include <proto/session.h>
#include <proto/pipe.h>
#include <proto/proto_http.h>
#include <proto/proto_tcp.h>
#include <proto/proxy.h>
#include <proto/queue.h>
#include <proto/server.h>
#include <proto/sample.h>
#include <proto/stick_table.h>
#include <proto/stream_interface.h>
#include <proto/task.h>

struct pool_head *pool2_session;
struct list sessions;

static int conn_session_complete(struct connection *conn);
static int conn_session_update(struct connection *conn);
static struct task *expire_mini_session(struct task *t);
int session_complete(struct session *s);

/* data layer callbacks for an embryonic session */
struct data_cb sess_conn_cb = {
	.recv = NULL,
	.send = NULL,
	.wake = conn_session_update,
	.init = conn_session_complete,
};

/* This function is called from the protocol layer accept() in order to
 * instanciate a new embryonic session on behalf of a given listener and
 * frontend. It returns a positive value upon success, 0 if the connection
 * can be ignored, or a negative value upon critical failure. The accepted
 * file descriptor is closed if we return <= 0.
 */
int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
{
	struct proxy *p = l->frontend;
	struct session *s;
	struct task *t;
	int ret;


	ret = -1; /* assume unrecoverable error by default */

	if (unlikely((s = pool_alloc2(pool2_session)) == NULL))
		goto out_close;

	if (unlikely((s->si[0].conn = pool_alloc2(pool2_connection)) == NULL))
		goto out_fail_conn0;

	if (unlikely((s->si[1].conn = pool_alloc2(pool2_connection)) == NULL))
		goto out_fail_conn1;

	/* minimum session initialization required for an embryonic session is
	 * fairly low. We need very little to execute L4 ACLs, then we need a
	 * task to make the client-side connection live on its own.
	 *  - flags
	 *  - stick-entry tracking
	 */
	s->flags = 0;
	s->logs.logwait = p->to_log;
	s->stkctr1_entry = NULL;
	s->stkctr2_entry = NULL;
	s->stkctr1_table = NULL;
	s->stkctr2_table = NULL;

	s->listener = l;
	s->fe  = p;

	/* OK, we're keeping the session, so let's properly initialize the session */
	s->si[0].conn->t.sock.fd = cfd;
	s->si[0].conn->ctrl = l->proto;
	s->si[0].conn->flags = CO_FL_NONE;
	s->si[0].conn->addr.from = *addr;
	s->si[0].conn->target = &l->obj_type;

	s->logs.accept_date = date; /* user-visible date for logging */
	s->logs.tv_accept = now;  /* corrected date for internal use */
	s->uniq_id = totalconn;
	p->feconn++;
	/* This session was accepted, count it now */
	if (p->feconn > p->fe_counters.conn_max)
		p->fe_counters.conn_max = p->feconn;

	proxy_inc_fe_conn_ctr(l, p);

	/* now evaluate the tcp-request layer4 rules. Since we expect to be able
	 * to abort right here as soon as possible, we check the rules before
	 * even initializing the stream interfaces.
	 */
	if ((l->options & LI_O_TCP_RULES) && !tcp_exec_req_rules(s)) {
		/* let's do a no-linger now to close with a single RST. */
		setsockopt(cfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger));
		ret = 0; /* successful termination */
		goto out_free_session;
	}

#ifndef USE_ACCEPT4
	/* Adjust some socket options if the connection was accepted by a plain
	 * accept() syscall.
	 */
	if (unlikely(fcntl(cfd, F_SETFL, O_NONBLOCK) == -1))
		goto out_free_session;
#endif

	/* monitor-net and health mode are processed immediately after TCP
	 * connection rules. This way it's possible to block them, but they
	 * never use the lower data layers, they send directly over the socket,
	 * as they were designed for. We first flush the socket receive buffer
	 * in order to avoid emission of an RST by the system. We ignore any
	 * error.
	 */
	if (unlikely((p->mode == PR_MODE_HEALTH) ||
		     ((l->options & LI_O_CHK_MONNET) &&
		      addr->ss_family == AF_INET &&
		      (((struct sockaddr_in *)addr)->sin_addr.s_addr & p->mon_mask.s_addr) == p->mon_net.s_addr))) {
		/* we have 4 possibilities here :
		 *  - HTTP mode, from monitoring address => send "HTTP/1.0 200 OK"
		 *  - HEALTH mode with HTTP check => send "HTTP/1.0 200 OK"
		 *  - HEALTH mode without HTTP check => just send "OK"
		 *  - TCP mode from monitoring address => just close
		 */
		recv(cfd, trash.str, trash.size, MSG_DONTWAIT);
		if (p->mode == PR_MODE_HTTP ||
		    (p->mode == PR_MODE_HEALTH && (p->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK))
			send(cfd, "HTTP/1.0 200 OK\r\n\r\n", 19, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
		else if (p->mode == PR_MODE_HEALTH)
			send(cfd, "OK\n", 3, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
		ret = 0;
		goto out_free_session;
	}


	/* wait for a PROXY protocol header */
	if (l->options & LI_O_ACC_PROXY) {
		s->si[0].conn->flags |= CO_FL_ACCEPT_PROXY;
		conn_sock_want_recv(s->si[0].conn);
	}

	if (unlikely((t = task_new()) == NULL))
		goto out_free_session;

	t->context = s;
	t->nice = l->nice;
	s->task = t;

	/* Add the various callbacks. Right now the transport layer is present
	 * but not initialized. Also note we need to be careful as the stream
	 * int is not initialized yet.
	 */
	conn_prepare(s->si[0].conn, &sess_conn_cb, l->proto, l->xprt, s);

	/* finish initialization of the accepted file descriptor */
	fd_insert(cfd);
	fdtab[cfd].owner = s->si[0].conn;
	fdtab[cfd].iocb = conn_fd_handler;
	conn_data_want_recv(s->si[0].conn);
	if (conn_xprt_init(s->si[0].conn) < 0)
		goto out_free_task;

	/* OK, now either we have a pending handshake to execute with and
	 * then we must return to the I/O layer, or we can proceed with the
	 * end of the session initialization. In case of handshake, we also
	 * set the I/O timeout to the frontend's client timeout.
	 */

	if (s->si[0].conn->flags & CO_FL_HANDSHAKE) {
		t->process = expire_mini_session;
		t->expire = tick_add_ifset(now_ms, p->timeout.client);
		task_queue(t);
		s->si[0].conn->flags |= CO_FL_INIT_DATA | CO_FL_WAKE_DATA;
		return 1;
	}

	/* OK let's complete session initialization since there is no handshake */
	s->si[0].conn->flags |= CO_FL_CONNECTED;
	ret = session_complete(s);
	if (ret > 0)
		return ret;

	/* Error unrolling */
 out_free_task:
	task_free(t);
 out_free_session:
	p->feconn--;
	if (s->stkctr1_entry || s->stkctr2_entry)
		session_store_counters(s);
	pool_free2(pool2_connection, s->si[1].conn);
 out_fail_conn1:
	pool_free2(pool2_connection, s->si[0].conn);
 out_fail_conn0:
	pool_free2(pool2_session, s);
 out_close:
	if (ret < 0 && l->xprt == &raw_sock && p->mode == PR_MODE_HTTP) {
		/* critical error, no more memory, try to emit a 500 response */
		struct chunk *err_msg = http_error_message(s, HTTP_ERR_500);
		send(cfd, err_msg->str, err_msg->len, MSG_DONTWAIT|MSG_NOSIGNAL);
	}

	if (fdtab[cfd].owner)
		fd_delete(cfd);
	else
		close(cfd);
	return ret;
}

/* This function kills an existing embryonic session. It stops the connection's
 * transport layer, releases assigned resources, resumes the listener if it was
 * disabled and finally kills the file descriptor.
 */
static void kill_mini_session(struct session *s)
{
	/* kill the connection now */
	conn_xprt_close(s->si[0].conn);

	s->fe->feconn--;
	if (s->stkctr1_entry || s->stkctr2_entry)
		session_store_counters(s);

	if (!(s->listener->options & LI_O_UNLIMITED))
		actconn--;
	jobs--;
	s->listener->nbconn--;
	if (s->listener->state == LI_FULL)
		resume_listener(s->listener);

	/* Dequeues all of the listeners waiting for a resource */
	if (!LIST_ISEMPTY(&global_listener_queue))
		dequeue_all_listeners(&global_listener_queue);

	if (!LIST_ISEMPTY(&s->fe->listener_queue) &&
	    (!s->fe->fe_sps_lim || freq_ctr_remain(&s->fe->fe_sess_per_sec, s->fe->fe_sps_lim, 0) > 0))
		dequeue_all_listeners(&s->fe->listener_queue);

	task_delete(s->task);
	task_free(s->task);

	if (fdtab[s->si[0].conn->t.sock.fd].owner)
		fd_delete(s->si[0].conn->t.sock.fd);
	else
		close(s->si[0].conn->t.sock.fd);

	pool_free2(pool2_connection, s->si[1].conn);
	pool_free2(pool2_connection, s->si[0].conn);
	pool_free2(pool2_session, s);
}

/* Finish initializing a session from a connection, or kills it if the
 * connection shows and error. Returns <0 if the connection was killed.
 */
static int conn_session_complete(struct connection *conn)
{
	struct session *s = conn->owner;

	if (!(conn->flags & CO_FL_ERROR) && (session_complete(s) > 0)) {
		conn->flags &= ~CO_FL_INIT_DATA;
		return 0;
	}

	/* kill the connection now */
	kill_mini_session(s);
	return -1;
}

/* Update an embryonic session status. The connection is killed in case of
 * error, and <0 will be returned. Otherwise it does nothing.
 */
static int conn_session_update(struct connection *conn)
{
	if (conn->flags & CO_FL_ERROR) {
		kill_mini_session(conn->owner);
		return -1;
	}
	return 0;
}

/* Manages embryonic sessions timeout. It is only called when the timeout
 * strikes and performs the required cleanup.
 */
static struct task *expire_mini_session(struct task *t)
{
	struct session *s = t->context;

	if (!(t->state & TASK_WOKEN_TIMER))
		return t;

	kill_mini_session(s);
	return NULL;
}

/* This function is called from the I/O handler which detects the end of
 * handshake, in order to complete initialization of a valid session. It must
 * be called with an embryonic session. It returns a positive value upon
 * success, 0 if the connection can be ignored, or a negative value upon
 * critical failure. The accepted file descriptor is closed if we return <= 0.
 */
int session_complete(struct session *s)
{
	struct listener *l = s->listener;
	struct proxy *p = s->fe;
	struct http_txn *txn;
	struct task *t = s->task;
	int ret;

	ret = -1; /* assume unrecoverable error by default */

	/* OK, we're keeping the session, so let's properly initialize the session */
	LIST_ADDQ(&sessions, &s->list);
	LIST_INIT(&s->back_refs);
	si_takeover_conn(&s->si[0], l->proto, l->xprt);
	s->flags |= SN_INITIALIZED;

	s->unique_id = NULL;

	t->process = l->handler;
	t->context = s;
	t->expire = TICK_ETERNITY;

	/* Note: initially, the session's backend points to the frontend.
	 * This changes later when switching rules are executed or
	 * when the default backend is assigned.
	 */
	s->be  = s->fe;
	s->req = s->rep = NULL; /* will be allocated later */
	s->comp_algo = NULL;

	/* Let's count a session now */
	proxy_inc_fe_sess_ctr(l, p);
	if (s->stkctr1_entry) {
		void *ptr;

		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_SESS_CNT);
		if (ptr)
			stktable_data_cast(ptr, sess_cnt)++;

		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_SESS_RATE);
		if (ptr)
			update_freq_ctr_period(&stktable_data_cast(ptr, sess_rate),
					       s->stkctr1_table->data_arg[STKTABLE_DT_SESS_RATE].u, 1);
	}

	if (s->stkctr2_entry) {
		void *ptr;

		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_SESS_CNT);
		if (ptr)
			stktable_data_cast(ptr, sess_cnt)++;

		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_SESS_RATE);
		if (ptr)
			update_freq_ctr_period(&stktable_data_cast(ptr, sess_rate),
					       s->stkctr2_table->data_arg[STKTABLE_DT_SESS_RATE].u, 1);
	}

	/* this part should be common with other protocols */
	s->si[0].owner     = t;
	s->si[0].state     = s->si[0].prev_state = SI_ST_EST;
	s->si[0].err_type  = SI_ET_NONE;
	s->si[0].err_loc   = NULL;
	s->si[0].release   = NULL;
	s->si[0].send_proxy_ofs = 0;
	s->si[0].exp       = TICK_ETERNITY;
	s->si[0].flags     = SI_FL_NONE;

	if (likely(s->fe->options2 & PR_O2_INDEPSTR))
		s->si[0].flags |= SI_FL_INDEP_STR;

	/* pre-initialize the other side's stream interface to an INIT state. The
	 * callbacks will be initialized before attempting to connect.
	 */
	s->si[1].conn->t.sock.fd = -1; /* just to help with debugging */
	s->si[1].conn->flags = CO_FL_NONE;
	s->si[1].owner     = t;
	s->si[1].state     = s->si[1].prev_state = SI_ST_INI;
	s->si[1].err_type  = SI_ET_NONE;
	s->si[1].conn_retries = 0;  /* used for logging too */
	s->si[1].err_loc   = NULL;
	s->si[1].release   = NULL;
	s->si[1].send_proxy_ofs = 0;
	s->si[1].conn->target = NULL;
	si_prepare_embedded(&s->si[1]);
	s->si[1].exp       = TICK_ETERNITY;
	s->si[1].flags     = SI_FL_NONE;

	if (likely(s->fe->options2 & PR_O2_INDEPSTR))
		s->si[1].flags |= SI_FL_INDEP_STR;

	session_init_srv_conn(s);
	s->target = NULL;
	s->pend_pos = NULL;

	/* init store persistence */
	s->store_count = 0;

	if (unlikely((s->req = pool_alloc2(pool2_channel)) == NULL))
		goto out_free_task; /* no memory */

	if (unlikely((s->req->buf = pool_alloc2(pool2_buffer)) == NULL))
		goto out_free_req; /* no memory */

	if (unlikely((s->rep = pool_alloc2(pool2_channel)) == NULL))
		goto out_free_req_buf; /* no memory */

	if (unlikely((s->rep->buf = pool_alloc2(pool2_buffer)) == NULL))
		goto out_free_rep; /* no memory */

	/* initialize the request buffer */
	s->req->buf->size = global.tune.bufsize;
	channel_init(s->req);
	s->req->prod = &s->si[0];
	s->req->cons = &s->si[1];
	s->si[0].ib = s->si[1].ob = s->req;
	s->req->flags |= CF_READ_ATTACHED; /* the producer is already connected */

	/* activate default analysers enabled for this listener */
	s->req->analysers = l->analysers;

	s->req->wto = TICK_ETERNITY;
	s->req->rto = TICK_ETERNITY;
	s->req->rex = TICK_ETERNITY;
	s->req->wex = TICK_ETERNITY;
	s->req->analyse_exp = TICK_ETERNITY;

	/* initialize response buffer */
	s->rep->buf->size = global.tune.bufsize;
	channel_init(s->rep);
	s->rep->prod = &s->si[1];
	s->rep->cons = &s->si[0];
	s->si[0].ob = s->si[1].ib = s->rep;
	s->rep->analysers = 0;

	if (s->fe->options2 & PR_O2_NODELAY) {
		s->req->flags |= CF_NEVER_WAIT;
		s->rep->flags |= CF_NEVER_WAIT;
	}

	s->rep->rto = TICK_ETERNITY;
	s->rep->wto = TICK_ETERNITY;
	s->rep->rex = TICK_ETERNITY;
	s->rep->wex = TICK_ETERNITY;
	s->rep->analyse_exp = TICK_ETERNITY;

	txn = &s->txn;
	/* Those variables will be checked and freed if non-NULL in
	 * session.c:session_free(). It is important that they are
	 * properly initialized.
	 */
	txn->sessid = NULL;
	txn->srv_cookie = NULL;
	txn->cli_cookie = NULL;
	txn->uri = NULL;
	txn->req.cap = NULL;
	txn->rsp.cap = NULL;
	txn->hdr_idx.v = NULL;
	txn->hdr_idx.size = txn->hdr_idx.used = 0;
	txn->req.flags = 0;
	txn->rsp.flags = 0;
	/* the HTTP messages need to know what buffer they're associated with */
	txn->req.chn = s->req;
	txn->rsp.chn = s->rep;

	/* finish initialization of the accepted file descriptor */
	conn_data_want_recv(s->si[0].conn);

	if (p->accept && (ret = p->accept(s)) <= 0) {
		/* Either we had an unrecoverable error (<0) or work is
		 * finished (=0, eg: monitoring), in both situations,
		 * we can release everything and close.
		 */
		goto out_free_rep_buf;
	}

	/* if logs require transport layer information, note it on the connection */
	if (s->logs.logwait & LW_XPRT)
		s->si[0].conn->flags |= CO_FL_XPRT_TRACKED;

	/* we want the connection handler to notify the stream interface about updates. */
	s->si[0].conn->flags |= CO_FL_WAKE_DATA;

	/* it is important not to call the wakeup function directly but to
	 * pass through task_wakeup(), because this one knows how to apply
	 * priorities to tasks.
	 */
	task_wakeup(t, TASK_WOKEN_INIT);
	return 1;

	/* Error unrolling */
 out_free_rep_buf:
	pool_free2(pool2_buffer, s->rep->buf);
 out_free_rep:
	pool_free2(pool2_channel, s->rep);
 out_free_req_buf:
	pool_free2(pool2_buffer, s->req->buf);
 out_free_req:
	pool_free2(pool2_channel, s->req);
 out_free_task:
	return ret;
}

/*
 * frees  the context associated to a session. It must have been removed first.
 */
static void session_free(struct session *s)
{
	struct http_txn *txn = &s->txn;
	struct proxy *fe = s->fe;
	struct bref *bref, *back;
	int i;

	if (s->pend_pos)
		pendconn_free(s->pend_pos);

	if (objt_server(s->target)) { /* there may be requests left pending in queue */
		if (s->flags & SN_CURR_SESS) {
			s->flags &= ~SN_CURR_SESS;
			objt_server(s->target)->cur_sess--;
		}
		if (may_dequeue_tasks(objt_server(s->target), s->be))
			process_srv_queue(objt_server(s->target));
	}

	if (unlikely(s->srv_conn)) {
		/* the session still has a reserved slot on a server, but
		 * it should normally be only the same as the one above,
		 * so this should not happen in fact.
		 */
		sess_change_server(s, NULL);
	}

	if (s->comp_algo) {
		s->comp_algo->end(&s->comp_ctx);
		s->comp_algo = NULL;
	}

	if (s->req->pipe)
		put_pipe(s->req->pipe);

	if (s->rep->pipe)
		put_pipe(s->rep->pipe);

	pool_free2(pool2_buffer, s->req->buf);
	pool_free2(pool2_buffer, s->rep->buf);

	pool_free2(pool2_channel, s->req);
	pool_free2(pool2_channel, s->rep);

	http_end_txn(s);

	/* ensure the client-side transport layer is destroyed */
	s->si[0].conn->flags &= ~CO_FL_XPRT_TRACKED;
	conn_xprt_close(s->si[0].conn);

	for (i = 0; i < s->store_count; i++) {
		if (!s->store[i].ts)
			continue;
		stksess_free(s->store[i].table, s->store[i].ts);
		s->store[i].ts = NULL;
	}

	pool_free2(pool2_hdr_idx, txn->hdr_idx.v);
	if (fe) {
		pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
		pool_free2(fe->req_cap_pool, txn->req.cap);
	}

	if (s->stkctr1_entry || s->stkctr2_entry)
		session_store_counters(s);

	list_for_each_entry_safe(bref, back, &s->back_refs, users) {
		/* we have to unlink all watchers. We must not relink them if
		 * this session was the last one in the list.
		 */
		LIST_DEL(&bref->users);
		LIST_INIT(&bref->users);
		if (s->list.n != &sessions)
			LIST_ADDQ(&LIST_ELEM(s->list.n, struct session *, list)->back_refs, &bref->users);
		bref->ref = s->list.n;
	}
	LIST_DEL(&s->list);
	pool_free2(pool2_connection, s->si[1].conn);
	pool_free2(pool2_connection, s->si[0].conn);
	pool_free2(pool2_session, s);

	/* We may want to free the maximum amount of pools if the proxy is stopping */
	if (fe && unlikely(fe->state == PR_STSTOPPED)) {
		pool_flush2(pool2_buffer);
		pool_flush2(pool2_channel);
		pool_flush2(pool2_hdr_idx);
		pool_flush2(pool2_requri);
		pool_flush2(pool2_capture);
		pool_flush2(pool2_session);
		pool_flush2(fe->req_cap_pool);
		pool_flush2(fe->rsp_cap_pool);
	}
}


/* perform minimal intializations, report 0 in case of error, 1 if OK. */
int init_session()
{
	LIST_INIT(&sessions);
	pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED);
	return pool2_session != NULL;
}

void session_process_counters(struct session *s)
{
	unsigned long long bytes;

	if (s->req) {
		bytes = s->req->total - s->logs.bytes_in;
		s->logs.bytes_in = s->req->total;
		if (bytes) {
			s->fe->fe_counters.bytes_in			+= bytes;

			s->be->be_counters.bytes_in			+= bytes;

			if (objt_server(s->target))
				objt_server(s->target)->counters.bytes_in		+= bytes;

			if (s->listener->counters)
				s->listener->counters->bytes_in		+= bytes;

			if (s->stkctr2_entry) {
				void *ptr;

				ptr = stktable_data_ptr(s->stkctr2_table,
							s->stkctr2_entry,
							STKTABLE_DT_BYTES_IN_CNT);
				if (ptr)
					stktable_data_cast(ptr, bytes_in_cnt) += bytes;

				ptr = stktable_data_ptr(s->stkctr2_table,
							s->stkctr2_entry,
							STKTABLE_DT_BYTES_IN_RATE);
				if (ptr)
					update_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
							       s->stkctr2_table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes);
			}

			if (s->stkctr1_entry) {
				void *ptr;

				ptr = stktable_data_ptr(s->stkctr1_table,
							s->stkctr1_entry,
							STKTABLE_DT_BYTES_IN_CNT);
				if (ptr)
					stktable_data_cast(ptr, bytes_in_cnt) += bytes;

				ptr = stktable_data_ptr(s->stkctr1_table,
							s->stkctr1_entry,
							STKTABLE_DT_BYTES_IN_RATE);
				if (ptr)
					update_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
							       s->stkctr1_table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes);
			}
		}
	}

	if (s->rep) {
		bytes = s->rep->total - s->logs.bytes_out;
		s->logs.bytes_out = s->rep->total;
		if (bytes) {
			s->fe->fe_counters.bytes_out			+= bytes;

			s->be->be_counters.bytes_out			+= bytes;

			if (objt_server(s->target))
				objt_server(s->target)->counters.bytes_out		+= bytes;

			if (s->listener->counters)
				s->listener->counters->bytes_out	+= bytes;

			if (s->stkctr2_entry) {
				void *ptr;

				ptr = stktable_data_ptr(s->stkctr2_table,
							s->stkctr2_entry,
							STKTABLE_DT_BYTES_OUT_CNT);
				if (ptr)
					stktable_data_cast(ptr, bytes_out_cnt) += bytes;

				ptr = stktable_data_ptr(s->stkctr2_table,
							s->stkctr2_entry,
							STKTABLE_DT_BYTES_OUT_RATE);
				if (ptr)
					update_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
							       s->stkctr2_table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes);
			}

			if (s->stkctr1_entry) {
				void *ptr;

				ptr = stktable_data_ptr(s->stkctr1_table,
							s->stkctr1_entry,
							STKTABLE_DT_BYTES_OUT_CNT);
				if (ptr)
					stktable_data_cast(ptr, bytes_out_cnt) += bytes;

				ptr = stktable_data_ptr(s->stkctr1_table,
							s->stkctr1_entry,
							STKTABLE_DT_BYTES_OUT_RATE);
				if (ptr)
					update_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
							       s->stkctr1_table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes);
			}
		}
	}
}

/* This function is called with (si->state == SI_ST_CON) meaning that a
 * connection was attempted and that the file descriptor is already allocated.
 * We must check for establishment, error and abort. Possible output states
 * are SI_ST_EST (established), SI_ST_CER (error), SI_ST_DIS (abort), and
 * SI_ST_CON (no change). The function returns 0 if it switches to SI_ST_CER,
 * otherwise 1.
 */
static int sess_update_st_con_tcp(struct session *s, struct stream_interface *si)
{
	struct channel *req = si->ob;
	struct channel *rep = si->ib;

	/* If we got an error, or if nothing happened and the connection timed
	 * out, we must give up. The CER state handler will take care of retry
	 * attempts and error reports.
	 */
	if (unlikely(si->flags & (SI_FL_EXP|SI_FL_ERR))) {
		if (unlikely(si->ob->flags & CF_WRITE_PARTIAL)) {
			/* Some data were sent past the connection establishment,
			 * so we need to pretend we're established to log correctly
			 * and let later states handle the failure.
			 */
			s->logs.t_connect = tv_ms_elapsed(&s->logs.tv_accept, &now);
			si->exp      = TICK_ETERNITY;
			si->state    = SI_ST_EST;
			si->err_type = SI_ET_DATA_ERR;
			si->ib->flags |= CF_READ_ERROR | CF_WRITE_ERROR;
			si->err_loc = objt_server(s->target);
			return 1;
		}
		si->exp   = TICK_ETERNITY;
		si->state = SI_ST_CER;
		fd_delete(si->conn->t.sock.fd);

		conn_xprt_close(si->conn);
		if (si->release)
			si->release(si);

		if (si->err_type)
			return 0;

		si->err_loc = objt_server(s->target);
		if (si->flags & SI_FL_ERR)
			si->err_type = SI_ET_CONN_ERR;
		else
			si->err_type = SI_ET_CONN_TO;
		return 0;
	}

	/* OK, maybe we want to abort */
	if (unlikely((rep->flags & CF_SHUTW) ||
		     ((req->flags & CF_SHUTW_NOW) && /* FIXME: this should not prevent a connection from establishing */
		      ((!(req->flags & CF_WRITE_ACTIVITY) && channel_is_empty(req)) ||
		       s->be->options & PR_O_ABRT_CLOSE)))) {
		/* give up */
		si_shutw(si);
		si->err_type |= SI_ET_CONN_ABRT;
		si->err_loc  = objt_server(s->target);
		if (s->srv_error)
			s->srv_error(s, si);
		return 1;
	}

	/* we need to wait a bit more if there was no activity either */
	if (!(req->flags & CF_WRITE_ACTIVITY))
		return 1;

	/* OK, this means that a connection succeeded. The caller will be
	 * responsible for handling the transition from CON to EST.
	 */
	s->logs.t_connect = tv_ms_elapsed(&s->logs.tv_accept, &now);
	si->exp      = TICK_ETERNITY;
	si->state    = SI_ST_EST;
	si->err_type = SI_ET_NONE;
	si->err_loc  = NULL;
	return 1;
}

/* This function is called with (si->state == SI_ST_CER) meaning that a
 * previous connection attempt has failed and that the file descriptor
 * has already been released. Possible causes include asynchronous error
 * notification and time out. Possible output states are SI_ST_CLO when
 * retries are exhausted, SI_ST_TAR when a delay is wanted before a new
 * connection attempt, SI_ST_ASS when it's wise to retry on the same server,
 * and SI_ST_REQ when an immediate redispatch is wanted. The buffers are
 * marked as in error state. It returns 0.
 */
static int sess_update_st_cer(struct session *s, struct stream_interface *si)
{
	/* we probably have to release last session from the server */
	if (objt_server(s->target)) {
		health_adjust(objt_server(s->target), HANA_STATUS_L4_ERR);

		if (s->flags & SN_CURR_SESS) {
			s->flags &= ~SN_CURR_SESS;
			objt_server(s->target)->cur_sess--;
		}
	}

	/* ensure that we have enough retries left */
	si->conn_retries--;
	if (si->conn_retries < 0) {
		if (!si->err_type) {
			si->err_type = SI_ET_CONN_ERR;
			si->err_loc = objt_server(s->target);
		}

		if (objt_server(s->target))
			objt_server(s->target)->counters.failed_conns++;
		s->be->be_counters.failed_conns++;
		sess_change_server(s, NULL);
		if (may_dequeue_tasks(objt_server(s->target), s->be))
			process_srv_queue(objt_server(s->target));

		/* shutw is enough so stop a connecting socket */
		si_shutw(si);
		si->ob->flags |= CF_WRITE_ERROR;
		si->ib->flags |= CF_READ_ERROR;

		si->state = SI_ST_CLO;
		if (s->srv_error)
			s->srv_error(s, si);
		return 0;
	}

	/* If the "redispatch" option is set on the backend, we are allowed to
	 * retry on another server for the last retry. In order to achieve this,
	 * we must mark the session unassigned, and eventually clear the DIRECT
	 * bit to ignore any persistence cookie. We won't count a retry nor a
	 * redispatch yet, because this will depend on what server is selected.
	 */
	if (objt_server(s->target) && si->conn_retries == 0 &&
	    s->be->options & PR_O_REDISP && !(s->flags & SN_FORCE_PRST)) {
		sess_change_server(s, NULL);
		if (may_dequeue_tasks(objt_server(s->target), s->be))
			process_srv_queue(objt_server(s->target));

		s->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
		si->state = SI_ST_REQ;
	} else {
		if (objt_server(s->target))
			objt_server(s->target)->counters.retries++;
		s->be->be_counters.retries++;
		si->state = SI_ST_ASS;
	}

	if (si->flags & SI_FL_ERR) {
		/* The error was an asynchronous connection error, and we will
		 * likely have to retry connecting to the same server, most
		 * likely leading to the same result. To avoid this, we wait
		 * one second before retrying.
		 */

		if (!si->err_type)
			si->err_type = SI_ET_CONN_ERR;

		si->state = SI_ST_TAR;
		si->exp = tick_add(now_ms, MS_TO_TICKS(1000));
		return 0;
	}
	return 0;
}

/*
 * This function handles the transition between the SI_ST_CON state and the
 * SI_ST_EST state. It must only be called after switching from SI_ST_CON (or
 * SI_ST_INI) to SI_ST_EST, but only when a ->proto is defined.
 */
static void sess_establish(struct session *s, struct stream_interface *si)
{
	struct channel *req = si->ob;
	struct channel *rep = si->ib;

	if (objt_server(s->target))
		health_adjust(objt_server(s->target), HANA_STATUS_L4_OK);

	if (s->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
		/* if the user wants to log as soon as possible, without counting
		 * bytes from the server, then this is the right moment. */
		if (s->fe->to_log && !(s->logs.logwait & LW_BYTES)) {
			s->logs.t_close = s->logs.t_connect; /* to get a valid end date */
			s->do_log(s);
		}
	}
	else {
		s->txn.rsp.msg_state = HTTP_MSG_RPBEFORE;
		/* reset hdr_idx which was already initialized by the request.
		 * right now, the http parser does it.
		 * hdr_idx_init(&s->txn.hdr_idx);
		 */
	}

	rep->analysers |= s->fe->fe_rsp_ana | s->be->be_rsp_ana;
	rep->flags |= CF_READ_ATTACHED; /* producer is now attached */
	if (si_ctrl(si)) {
		/* real connections have timeouts */
		req->wto = s->be->timeout.server;
		rep->rto = s->be->timeout.server;
	}
	req->wex = TICK_ETERNITY;
}

/* Update stream interface status for input states SI_ST_ASS, SI_ST_QUE, SI_ST_TAR.
 * Other input states are simply ignored.
 * Possible output states are SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ, SI_ST_CON.
 * Flags must have previously been updated for timeouts and other conditions.
 */
static void sess_update_stream_int(struct session *s, struct stream_interface *si)
{
	struct server *srv = objt_server(s->target);

	DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d\n",
		now_ms, __FUNCTION__,
		s,
		s->req, s->rep,
		s->req->rex, s->rep->wex,
		s->req->flags, s->rep->flags,
		s->req->buf->i, s->req->buf->o, s->rep->buf->i, s->rep->buf->o, s->rep->cons->state, s->req->cons->state);

	if (si->state == SI_ST_ASS) {
		/* Server assigned to connection request, we have to try to connect now */
		int conn_err;

		conn_err = connect_server(s);
		srv = objt_server(s->target);

		if (conn_err == SN_ERR_NONE) {
			/* state = SI_ST_CON now */
			if (srv)
				srv_inc_sess_ctr(srv);
			return;
		}

		/* We have received a synchronous error. We might have to
		 * abort, retry immediately or redispatch.
		 */
		if (conn_err == SN_ERR_INTERNAL) {
			if (!si->err_type) {
				si->err_type = SI_ET_CONN_OTHER;
				si->err_loc  = srv;
			}

			if (srv)
				srv_inc_sess_ctr(srv);
			if (srv)
				srv->counters.failed_conns++;
			s->be->be_counters.failed_conns++;

			/* release other sessions waiting for this server */
			sess_change_server(s, NULL);
			if (may_dequeue_tasks(srv, s->be))
				process_srv_queue(srv);

			/* Failed and not retryable. */
			si_shutr(si);
			si_shutw(si);
			si->ob->flags |= CF_WRITE_ERROR;

			s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);

			/* no session was ever accounted for this server */
			si->state = SI_ST_CLO;
			if (s->srv_error)
				s->srv_error(s, si);
			return;
		}

		/* We are facing a retryable error, but we don't want to run a
		 * turn-around now, as the problem is likely a source port
		 * allocation problem, so we want to retry now.
		 */
		si->state = SI_ST_CER;
		si->flags &= ~SI_FL_ERR;
		sess_update_st_cer(s, si);
		/* now si->state is one of SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ */
		return;
	}
	else if (si->state == SI_ST_QUE) {
		/* connection request was queued, check for any update */
		if (!s->pend_pos) {
			/* The connection is not in the queue anymore. Either
			 * we have a server connection slot available and we
			 * go directly to the assigned state, or we need to
			 * load-balance first and go to the INI state.
			 */
			si->exp = TICK_ETERNITY;
			if (unlikely(!(s->flags & SN_ASSIGNED)))
				si->state = SI_ST_REQ;
			else {
				s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
				si->state = SI_ST_ASS;
			}
			return;
		}

		/* Connection request still in queue... */
		if (si->flags & SI_FL_EXP) {
			/* ... and timeout expired */
			si->exp = TICK_ETERNITY;
			s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
			if (srv)
				srv->counters.failed_conns++;
			s->be->be_counters.failed_conns++;
			si_shutr(si);
			si_shutw(si);
			si->ob->flags |= CF_WRITE_TIMEOUT;
			if (!si->err_type)
				si->err_type = SI_ET_QUEUE_TO;
			si->state = SI_ST_CLO;
			if (s->srv_error)
				s->srv_error(s, si);
			return;
		}

		/* Connection remains in queue, check if we have to abort it */
		if ((si->ob->flags & (CF_READ_ERROR)) ||
		    ((si->ob->flags & CF_SHUTW_NOW) &&   /* empty and client aborted */
		     (channel_is_empty(si->ob) || s->be->options & PR_O_ABRT_CLOSE))) {
			/* give up */
			si->exp = TICK_ETERNITY;
			s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
			si_shutr(si);
			si_shutw(si);
			si->err_type |= SI_ET_QUEUE_ABRT;
			si->state = SI_ST_CLO;
			if (s->srv_error)
				s->srv_error(s, si);
			return;
		}

		/* Nothing changed */
		return;
	}
	else if (si->state == SI_ST_TAR) {
		/* Connection request might be aborted */
		if ((si->ob->flags & (CF_READ_ERROR)) ||
		    ((si->ob->flags & CF_SHUTW_NOW) &&  /* empty and client aborted */
		     (channel_is_empty(si->ob) || s->be->options & PR_O_ABRT_CLOSE))) {
			/* give up */
			si->exp = TICK_ETERNITY;
			si_shutr(si);
			si_shutw(si);
			si->err_type |= SI_ET_CONN_ABRT;
			si->state = SI_ST_CLO;
			if (s->srv_error)
				s->srv_error(s, si);
			return;
		}

		if (!(si->flags & SI_FL_EXP))
			return;  /* still in turn-around */

		si->exp = TICK_ETERNITY;

		/* we keep trying on the same server as long as the session is
		 * marked "assigned".
		 * FIXME: Should we force a redispatch attempt when the server is down ?
		 */
		if (s->flags & SN_ASSIGNED)
			si->state = SI_ST_ASS;
		else
			si->state = SI_ST_REQ;
		return;
	}
}

/* Set correct session termination flags in case no analyser has done it. It
 * also counts a failed request if the server state has not reached the request
 * stage.
 */
static void sess_set_term_flags(struct session *s)
{
	if (!(s->flags & SN_FINST_MASK)) {
		if (s->si[1].state < SI_ST_REQ) {

			s->fe->fe_counters.failed_req++;
			if (s->listener->counters)
				s->listener->counters->failed_req++;

			s->flags |= SN_FINST_R;
		}
		else if (s->si[1].state == SI_ST_QUE)
			s->flags |= SN_FINST_Q;
		else if (s->si[1].state < SI_ST_EST)
			s->flags |= SN_FINST_C;
		else if (s->si[1].state == SI_ST_EST || s->si[1].prev_state == SI_ST_EST)
			s->flags |= SN_FINST_D;
		else
			s->flags |= SN_FINST_L;
	}
}

/* This function initiates a server connection request on a stream interface
 * already in SI_ST_REQ state. Upon success, the state goes to SI_ST_ASS,
 * indicating that a server has been assigned. It may also return SI_ST_QUE,
 * or SI_ST_CLO upon error.
 */
static void sess_prepare_conn_req(struct session *s, struct stream_interface *si)
{
	DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d\n",
		now_ms, __FUNCTION__,
		s,
		s->req, s->rep,
		s->req->rex, s->rep->wex,
		s->req->flags, s->rep->flags,
		s->req->buf->i, s->req->buf->o, s->rep->buf->i, s->rep->buf->o, s->rep->cons->state, s->req->cons->state);

	if (si->state != SI_ST_REQ)
		return;

	/* Try to assign a server */
	if (srv_redispatch_connect(s) != 0) {
		/* We did not get a server. Either we queued the
		 * connection request, or we encountered an error.
		 */
		if (si->state == SI_ST_QUE)
			return;

		/* we did not get any server, let's check the cause */
		si_shutr(si);
		si_shutw(si);
		si->ob->flags |= CF_WRITE_ERROR;
		if (!si->err_type)
			si->err_type = SI_ET_CONN_OTHER;
		si->state = SI_ST_CLO;
		if (s->srv_error)
			s->srv_error(s, si);
		return;
	}

	/* The server is assigned */
	s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
	si->state = SI_ST_ASS;
}

/* This stream analyser checks the switching rules and changes the backend
 * if appropriate. The default_backend rule is also considered, then the
 * target backend's forced persistence rules are also evaluated last if any.
 * It returns 1 if the processing can continue on next analysers, or zero if it
 * either needs more data or wants to immediately abort the request.
 */
static int process_switching_rules(struct session *s, struct channel *req, int an_bit)
{
	struct persist_rule *prst_rule;

	req->analysers &= ~an_bit;
	req->analyse_exp = TICK_ETERNITY;

	DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
		now_ms, __FUNCTION__,
		s,
		req,
		req->rex, req->wex,
		req->flags,
		req->buf->i,
		req->analysers);

	/* now check whether we have some switching rules for this request */
	if (!(s->flags & SN_BE_ASSIGNED)) {
		struct switching_rule *rule;

		list_for_each_entry(rule, &s->fe->switching_rules, list) {
			int ret;

			ret = acl_exec_cond(rule->cond, s->fe, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;

			if (ret) {
				if (!session_set_backend(s, rule->be.backend))
					goto sw_failed;
				break;
			}
		}

		/* To ensure correct connection accounting on the backend, we
		 * have to assign one if it was not set (eg: a listen). This
		 * measure also takes care of correctly setting the default
		 * backend if any.
		 */
		if (!(s->flags & SN_BE_ASSIGNED))
			if (!session_set_backend(s, s->fe->defbe.be ? s->fe->defbe.be : s->be))
				goto sw_failed;
	}

	/* we don't want to run the TCP or HTTP filters again if the backend has not changed */
	if (s->fe == s->be) {
		s->req->analysers &= ~AN_REQ_INSPECT_BE;
		s->req->analysers &= ~AN_REQ_HTTP_PROCESS_BE;
	}

	/* as soon as we know the backend, we must check if we have a matching forced or ignored
	 * persistence rule, and report that in the session.
	 */
	list_for_each_entry(prst_rule, &s->be->persist_rules, list) {
		int ret = 1;

		if (prst_rule->cond) {
	                ret = acl_exec_cond(prst_rule->cond, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (prst_rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			/* no rule, or the rule matches */
			if (prst_rule->type == PERSIST_TYPE_FORCE) {
				s->flags |= SN_FORCE_PRST;
			} else {
				s->flags |= SN_IGNORE_PRST;
			}
			break;
		}
	}

	return 1;

 sw_failed:
	/* immediately abort this request in case of allocation failure */
	channel_abort(s->req);
	channel_abort(s->rep);

	if (!(s->flags & SN_ERR_MASK))
		s->flags |= SN_ERR_RESOURCE;
	if (!(s->flags & SN_FINST_MASK))
		s->flags |= SN_FINST_R;

	s->txn.status = 500;
	s->req->analysers = 0;
	s->req->analyse_exp = TICK_ETERNITY;
	return 0;
}

/* This stream analyser works on a request. It applies all use-server rules on
 * it then returns 1. The data must already be present in the buffer otherwise
 * they won't match. It always returns 1.
 */
static int process_server_rules(struct session *s, struct channel *req, int an_bit)
{
	struct proxy *px = s->be;
	struct server_rule *rule;

	DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
		now_ms, __FUNCTION__,
		s,
		req,
		req->rex, req->wex,
		req->flags,
		req->buf->i + req->buf->o,
		req->analysers);

	if (!(s->flags & SN_ASSIGNED)) {
		list_for_each_entry(rule, &px->server_rules, list) {
			int ret;

			ret = acl_exec_cond(rule->cond, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;

			if (ret) {
				struct server *srv = rule->srv.ptr;

				if ((srv->state & SRV_RUNNING) ||
				    (px->options & PR_O_PERSIST) ||
				    (s->flags & SN_FORCE_PRST)) {
					s->flags |= SN_DIRECT | SN_ASSIGNED;
					s->target = &srv->obj_type;
					break;
				}
				/* if the server is not UP, let's go on with next rules
				 * just in case another one is suited.
				 */
			}
		}
	}

	req->analysers &= ~an_bit;
	req->analyse_exp = TICK_ETERNITY;
	return 1;
}

/* This stream analyser works on a request. It applies all sticking rules on
 * it then returns 1. The data must already be present in the buffer otherwise
 * they won't match. It always returns 1.
 */
static int process_sticking_rules(struct session *s, struct channel *req, int an_bit)
{
	struct proxy    *px   = s->be;
	struct sticking_rule  *rule;

	DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
		now_ms, __FUNCTION__,
		s,
		req,
		req->rex, req->wex,
		req->flags,
		req->buf->i,
		req->analysers);

	list_for_each_entry(rule, &px->sticking_rules, list) {
		int ret = 1 ;
		int i;

		for (i = 0; i < s->store_count; i++) {
			if (rule->table.t == s->store[i].table)
				break;
		}

		if (i !=  s->store_count)
			continue;

		if (rule->cond) {
	                ret = acl_exec_cond(rule->cond, px, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			struct stktable_key *key;

			key = stktable_fetch_key(rule->table.t, px, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->expr);
			if (!key)
				continue;

			if (rule->flags & STK_IS_MATCH) {
				struct stksess *ts;

				if ((ts = stktable_lookup_key(rule->table.t, key)) != NULL) {
					if (!(s->flags & SN_ASSIGNED)) {
						struct eb32_node *node;
						void *ptr;

						/* srv found in table */
						ptr = stktable_data_ptr(rule->table.t, ts, STKTABLE_DT_SERVER_ID);
						node = eb32_lookup(&px->conf.used_server_id, stktable_data_cast(ptr, server_id));
						if (node) {
							struct server *srv;

							srv = container_of(node, struct server, conf.id);
							if ((srv->state & SRV_RUNNING) ||
							    (px->options & PR_O_PERSIST) ||
							    (s->flags & SN_FORCE_PRST)) {
								s->flags |= SN_DIRECT | SN_ASSIGNED;
								s->target = &srv->obj_type;
							}
						}
					}
					stktable_touch(rule->table.t, ts, 1);
				}
			}
			if (rule->flags & STK_IS_STORE) {
				if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
					struct stksess *ts;

					ts = stksess_new(rule->table.t, key);
					if (ts) {
						s->store[s->store_count].table = rule->table.t;
						s->store[s->store_count++].ts = ts;
					}
				}
			}
		}
	}

	req->analysers &= ~an_bit;
	req->analyse_exp = TICK_ETERNITY;
	return 1;
}

/* This stream analyser works on a response. It applies all store rules on it
 * then returns 1. The data must already be present in the buffer otherwise
 * they won't match. It always returns 1.
 */
static int process_store_rules(struct session *s, struct channel *rep, int an_bit)
{
	struct proxy    *px   = s->be;
	struct sticking_rule  *rule;
	int i;

	DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
		now_ms, __FUNCTION__,
		s,
		rep,
		rep->rex, rep->wex,
		rep->flags,
		rep->buf->i,
		rep->analysers);

	list_for_each_entry(rule, &px->storersp_rules, list) {
		int ret = 1 ;
		int storereqidx = -1;

		for (i = 0; i < s->store_count; i++) {
			if (rule->table.t == s->store[i].table) {
				if (!(s->store[i].flags))
					storereqidx = i;
				break;
			}
		}

		if ((i !=  s->store_count) && (storereqidx == -1))
			continue;

		if (rule->cond) {
	                ret = acl_exec_cond(rule->cond, px, s, &s->txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
	                ret = acl_pass(ret);
			if (rule->cond->pol == ACL_COND_UNLESS)
				ret = !ret;
		}

		if (ret) {
			struct stktable_key *key;

			key = stktable_fetch_key(rule->table.t, px, s, &s->txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL, rule->expr);
			if (!key)
				continue;

			if (storereqidx != -1) {
				stksess_setkey(s->store[storereqidx].table, s->store[storereqidx].ts, key);
				s->store[storereqidx].flags = 1;
			}
			else if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
				struct stksess *ts;

				ts = stksess_new(rule->table.t, key);
				if (ts) {
					s->store[s->store_count].table = rule->table.t;
					s->store[s->store_count].flags = 1;
					s->store[s->store_count++].ts = ts;
				}
			}
		}
	}

	/* process store request and store response */
	for (i = 0; i < s->store_count; i++) {
		struct stksess *ts;
		void *ptr;

		if (objt_server(s->target) && objt_server(s->target)->state & SRV_NON_STICK) {
			stksess_free(s->store[i].table, s->store[i].ts);
			s->store[i].ts = NULL;
			continue;
		}

		ts = stktable_lookup(s->store[i].table, s->store[i].ts);
		if (ts) {
			/* the entry already existed, we can free ours */
			stktable_touch(s->store[i].table, ts, 1);
			stksess_free(s->store[i].table, s->store[i].ts);
		}
		else
			ts = stktable_store(s->store[i].table, s->store[i].ts, 1);

		s->store[i].ts = NULL;
		ptr = stktable_data_ptr(s->store[i].table, ts, STKTABLE_DT_SERVER_ID);
		stktable_data_cast(ptr, server_id) = objt_server(s->target)->puid;
	}
	s->store_count = 0; /* everything is stored */

	rep->analysers &= ~an_bit;
	rep->analyse_exp = TICK_ETERNITY;
	return 1;
}

/* This macro is very specific to the function below. See the comments in
 * process_session() below to understand the logic and the tests.
 */
#define UPDATE_ANALYSERS(real, list, back, flag) {			\
		list = (((list) & ~(flag)) | ~(back)) & (real);		\
		back = real;						\
		if (!(list))						\
			break;						\
		if (((list) ^ ((list) & ((list) - 1))) < (flag))	\
			continue;					\
}

/* Processes the client, server, request and response jobs of a session task,
 * then puts it back to the wait queue in a clean state, or cleans up its
 * resources if it must be deleted. Returns in <next> the date the task wants
 * to be woken up, or TICK_ETERNITY. In order not to call all functions for
 * nothing too many times, the request and response buffers flags are monitored
 * and each function is called only if at least another function has changed at
 * least one flag it is interested in.
 */
struct task *process_session(struct task *t)
{
	struct server *srv;
	struct session *s = t->context;
	unsigned int rqf_last, rpf_last;
	unsigned int rq_prod_last, rq_cons_last;
	unsigned int rp_cons_last, rp_prod_last;
	unsigned int req_ana_back;

	//DPRINTF(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
	//        s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s->rep->flags);

	/* this data may be no longer valid, clear it */
	memset(&s->txn.auth, 0, sizeof(s->txn.auth));

	/* This flag must explicitly be set every time */
	s->req->flags &= ~CF_READ_NOEXP;

	/* Keep a copy of req/rep flags so that we can detect shutdowns */
	rqf_last = s->req->flags & ~CF_MASK_ANALYSER;
	rpf_last = s->rep->flags & ~CF_MASK_ANALYSER;

	/* we don't want the stream interface functions to recursively wake us up */
	if (s->req->prod->owner == t)
		s->req->prod->flags |= SI_FL_DONT_WAKE;
	if (s->req->cons->owner == t)
		s->req->cons->flags |= SI_FL_DONT_WAKE;

	/* 1a: Check for low level timeouts if needed. We just set a flag on
	 * stream interfaces when their timeouts have expired.
	 */
	if (unlikely(t->state & TASK_WOKEN_TIMER)) {
		stream_int_check_timeouts(&s->si[0]);
		stream_int_check_timeouts(&s->si[1]);

		/* check channel timeouts, and close the corresponding stream interfaces
		 * for future reads or writes. Note: this will also concern upper layers
		 * but we do not touch any other flag. We must be careful and correctly
		 * detect state changes when calling them.
		 */

		channel_check_timeouts(s->req);

		if (unlikely((s->req->flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
			s->req->cons->flags |= SI_FL_NOLINGER;
			si_shutw(s->req->cons);
		}

		if (unlikely((s->req->flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
			if (s->req->prod->flags & SI_FL_NOHALF)
				s->req->prod->flags |= SI_FL_NOLINGER;
			si_shutr(s->req->prod);
		}

		channel_check_timeouts(s->rep);

		if (unlikely((s->rep->flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
			s->rep->cons->flags |= SI_FL_NOLINGER;
			si_shutw(s->rep->cons);
		}

		if (unlikely((s->rep->flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
			if (s->rep->prod->flags & SI_FL_NOHALF)
				s->rep->prod->flags |= SI_FL_NOLINGER;
			si_shutr(s->rep->prod);
		}

		/* Once in a while we're woken up because the task expires. But
		 * this does not necessarily mean that a timeout has been reached.
		 * So let's not run a whole session processing if only an expiration
		 * timeout needs to be refreshed.
		 */
		if (!((s->req->flags | s->rep->flags) &
		      (CF_SHUTR|CF_READ_ACTIVITY|CF_READ_TIMEOUT|CF_SHUTW|
		       CF_WRITE_ACTIVITY|CF_WRITE_TIMEOUT|CF_ANA_TIMEOUT)) &&
		    !((s->si[0].flags | s->si[1].flags) & (SI_FL_EXP|SI_FL_ERR)) &&
		    ((t->state & TASK_WOKEN_ANY) == TASK_WOKEN_TIMER))
			goto update_exp_and_leave;
	}

	/* 1b: check for low-level errors reported at the stream interface.
	 * First we check if it's a retryable error (in which case we don't
	 * want to tell the buffer). Otherwise we report the error one level
	 * upper by setting flags into the buffers. Note that the side towards
	 * the client cannot have connect (hence retryable) errors. Also, the
	 * connection setup code must be able to deal with any type of abort.
	 */
	srv = objt_server(s->target);
	if (unlikely(s->si[0].flags & SI_FL_ERR)) {
		if (s->si[0].state == SI_ST_EST || s->si[0].state == SI_ST_DIS) {
			si_shutr(&s->si[0]);
			si_shutw(&s->si[0]);
			stream_int_report_error(&s->si[0]);
			if (!(s->req->analysers) && !(s->rep->analysers)) {
				s->be->be_counters.cli_aborts++;
				s->fe->fe_counters.cli_aborts++;
				if (srv)
					srv->counters.cli_aborts++;
				if (!(s->flags & SN_ERR_MASK))
					s->flags |= SN_ERR_CLICL;
				if (!(s->flags & SN_FINST_MASK))
					s->flags |= SN_FINST_D;
			}
		}
	}

	if (unlikely(s->si[1].flags & SI_FL_ERR)) {
		if (s->si[1].state == SI_ST_EST || s->si[1].state == SI_ST_DIS) {
			si_shutr(&s->si[1]);
			si_shutw(&s->si[1]);
			stream_int_report_error(&s->si[1]);
			s->be->be_counters.failed_resp++;
			if (srv)
				srv->counters.failed_resp++;
			if (!(s->req->analysers) && !(s->rep->analysers)) {
				s->be->be_counters.srv_aborts++;
				s->fe->fe_counters.srv_aborts++;
				if (srv)
					srv->counters.srv_aborts++;
				if (!(s->flags & SN_ERR_MASK))
					s->flags |= SN_ERR_SRVCL;
				if (!(s->flags & SN_FINST_MASK))
					s->flags |= SN_FINST_D;
			}
		}
		/* note: maybe we should process connection errors here ? */
	}

	if (s->si[1].state == SI_ST_CON) {
		/* we were trying to establish a connection on the server side,
		 * maybe it succeeded, maybe it failed, maybe we timed out, ...
		 */
		if (unlikely(!sess_update_st_con_tcp(s, &s->si[1])))
			sess_update_st_cer(s, &s->si[1]);
		else if (s->si[1].state == SI_ST_EST)
			sess_establish(s, &s->si[1]);

		/* state is now one of SI_ST_CON (still in progress), SI_ST_EST
		 * (established), SI_ST_DIS (abort), SI_ST_CLO (last error),
		 * SI_ST_ASS/SI_ST_TAR/SI_ST_REQ for retryable errors.
		 */
	}

	rq_prod_last = s->si[0].state;
	rq_cons_last = s->si[1].state;
	rp_cons_last = s->si[0].state;
	rp_prod_last = s->si[1].state;

 resync_stream_interface:
	/* Check for connection closure */

	DPRINTF(stderr,
		"[%u] %s:%d: task=%p s=%p, sfl=0x%08x, rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d, cet=0x%x set=0x%x retr=%d\n",
		now_ms, __FUNCTION__, __LINE__,
		t,
		s, s->flags,
		s->req, s->rep,
		s->req->rex, s->rep->wex,
		s->req->flags, s->rep->flags,
		s->req->buf->i, s->req->buf->o, s->rep->buf->i, s->rep->buf->o, s->rep->cons->state, s->req->cons->state,
		s->rep->cons->err_type, s->req->cons->err_type,
		s->req->cons->conn_retries);

	/* nothing special to be done on client side */
	if (unlikely(s->req->prod->state == SI_ST_DIS))
		s->req->prod->state = SI_ST_CLO;

	/* When a server-side connection is released, we have to count it and
	 * check for pending connections on this server.
	 */
	if (unlikely(s->req->cons->state == SI_ST_DIS)) {
		s->req->cons->state = SI_ST_CLO;
		srv = objt_server(s->target);
		if (srv) {
			if (s->flags & SN_CURR_SESS) {
				s->flags &= ~SN_CURR_SESS;
				srv->cur_sess--;
			}
			sess_change_server(s, NULL);
			if (may_dequeue_tasks(srv, s->be))
				process_srv_queue(srv);
		}
	}

	/*
	 * Note: of the transient states (REQ, CER, DIS), only REQ may remain
	 * at this point.
	 */

 resync_request:
	/* Analyse request */
	if (((s->req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
	    ((s->req->flags ^ rqf_last) & CF_MASK_STATIC) ||
	    s->si[0].state != rq_prod_last ||
	    s->si[1].state != rq_cons_last) {
		unsigned int flags = s->req->flags;

		if (s->req->prod->state >= SI_ST_EST) {
			int max_loops = global.tune.maxpollevents;
			unsigned int ana_list;
			unsigned int ana_back;

			/* it's up to the analysers to stop new connections,
			 * disable reading or closing. Note: if an analyser
			 * disables any of these bits, it is responsible for
			 * enabling them again when it disables itself, so
			 * that other analysers are called in similar conditions.
			 */
			channel_auto_read(s->req);
			channel_auto_connect(s->req);
			channel_auto_close(s->req);

			/* We will call all analysers for which a bit is set in
			 * s->req->analysers, following the bit order from LSB
			 * to MSB. The analysers must remove themselves from
			 * the list when not needed. Any analyser may return 0
			 * to break out of the loop, either because of missing
			 * data to take a decision, or because it decides to
			 * kill the session. We loop at least once through each
			 * analyser, and we may loop again if other analysers
			 * are added in the middle.
			 *
			 * We build a list of analysers to run. We evaluate all
			 * of these analysers in the order of the lower bit to
			 * the higher bit. This ordering is very important.
			 * An analyser will often add/remove other analysers,
			 * including itself. Any changes to itself have no effect
			 * on the loop. If it removes any other analysers, we
			 * want those analysers not to be called anymore during
			 * this loop. If it adds an analyser that is located
			 * after itself, we want it to be scheduled for being
			 * processed during the loop. If it adds an analyser
			 * which is located before it, we want it to switch to
			 * it immediately, even if it has already been called
			 * once but removed since.
			 *
			 * In order to achieve this, we compare the analyser
			 * list after the call with a copy of it before the
			 * call. The work list is fed with analyser bits that
			 * appeared during the call. Then we compare previous
			 * work list with the new one, and check the bits that
			 * appeared. If the lowest of these bits is lower than
			 * the current bit, it means we have enabled a previous
			 * analyser and must immediately loop again.
			 */

			ana_list = ana_back = s->req->analysers;
			while (ana_list && max_loops--) {
				/* Warning! ensure that analysers are always placed in ascending order! */

				if (ana_list & AN_REQ_INSPECT_FE) {
					if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT_FE))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_INSPECT_FE);
				}

				if (ana_list & AN_REQ_WAIT_HTTP) {
					if (!http_wait_for_request(s, s->req, AN_REQ_WAIT_HTTP))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_WAIT_HTTP);
				}

				if (ana_list & AN_REQ_HTTP_PROCESS_FE) {
					if (!http_process_req_common(s, s->req, AN_REQ_HTTP_PROCESS_FE, s->fe))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_FE);
				}

				if (ana_list & AN_REQ_SWITCHING_RULES) {
					if (!process_switching_rules(s, s->req, AN_REQ_SWITCHING_RULES))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_SWITCHING_RULES);
				}

				if (ana_list & AN_REQ_INSPECT_BE) {
					if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT_BE))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_INSPECT_BE);
				}

				if (ana_list & AN_REQ_HTTP_PROCESS_BE) {
					if (!http_process_req_common(s, s->req, AN_REQ_HTTP_PROCESS_BE, s->be))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_BE);
				}

				if (ana_list & AN_REQ_HTTP_TARPIT) {
					if (!http_process_tarpit(s, s->req, AN_REQ_HTTP_TARPIT))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_TARPIT);
				}

				if (ana_list & AN_REQ_SRV_RULES) {
					if (!process_server_rules(s, s->req, AN_REQ_SRV_RULES))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_SRV_RULES);
				}

				if (ana_list & AN_REQ_HTTP_INNER) {
					if (!http_process_request(s, s->req, AN_REQ_HTTP_INNER))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_INNER);
				}

				if (ana_list & AN_REQ_HTTP_BODY) {
					if (!http_process_request_body(s, s->req, AN_REQ_HTTP_BODY))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_BODY);
				}

				if (ana_list & AN_REQ_PRST_RDP_COOKIE) {
					if (!tcp_persist_rdp_cookie(s, s->req, AN_REQ_PRST_RDP_COOKIE))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_PRST_RDP_COOKIE);
				}

				if (ana_list & AN_REQ_STICKING_RULES) {
					if (!process_sticking_rules(s, s->req, AN_REQ_STICKING_RULES))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_STICKING_RULES);
				}

				if (ana_list & AN_REQ_HTTP_XFER_BODY) {
					if (!http_request_forward_body(s, s->req, AN_REQ_HTTP_XFER_BODY))
						break;
					UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_XFER_BODY);
				}
				break;
			}
		}

		rq_prod_last = s->si[0].state;
		rq_cons_last = s->si[1].state;
		s->req->flags &= ~CF_WAKE_ONCE;
		rqf_last = s->req->flags;

		if ((s->req->flags ^ flags) & CF_MASK_STATIC)
			goto resync_request;
	}

	/* we'll monitor the request analysers while parsing the response,
	 * because some response analysers may indirectly enable new request
	 * analysers (eg: HTTP keep-alive).
	 */
	req_ana_back = s->req->analysers;

 resync_response:
	/* Analyse response */

	if (((s->rep->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
		 (s->rep->flags ^ rpf_last) & CF_MASK_STATIC ||
		 s->si[0].state != rp_cons_last ||
		 s->si[1].state != rp_prod_last) {
		unsigned int flags = s->rep->flags;

		if ((s->rep->flags & CF_MASK_ANALYSER) &&
		    (s->rep->analysers & AN_REQ_WAIT_HTTP)) {
			/* Due to HTTP pipelining, the HTTP request analyser might be waiting
			 * for some free space in the response buffer, so we might need to call
			 * it when something changes in the response buffer, but still we pass
			 * it the request buffer. Note that the SI state might very well still
			 * be zero due to us returning a flow of redirects!
			 */
			s->rep->analysers &= ~AN_REQ_WAIT_HTTP;
			s->req->flags |= CF_WAKE_ONCE;
		}

		if (s->rep->prod->state >= SI_ST_EST) {
			int max_loops = global.tune.maxpollevents;
			unsigned int ana_list;
			unsigned int ana_back;

			/* it's up to the analysers to stop disable reading or
			 * closing. Note: if an analyser disables any of these
			 * bits, it is responsible for enabling them again when
			 * it disables itself, so that other analysers are called
			 * in similar conditions.
			 */
			channel_auto_read(s->rep);
			channel_auto_close(s->rep);

			/* We will call all analysers for which a bit is set in
			 * s->rep->analysers, following the bit order from LSB
			 * to MSB. The analysers must remove themselves from
			 * the list when not needed. Any analyser may return 0
			 * to break out of the loop, either because of missing
			 * data to take a decision, or because it decides to
			 * kill the session. We loop at least once through each
			 * analyser, and we may loop again if other analysers
			 * are added in the middle.
			 */

			ana_list = ana_back = s->rep->analysers;
			while (ana_list && max_loops--) {
				/* Warning! ensure that analysers are always placed in ascending order! */

				if (ana_list & AN_RES_INSPECT) {
					if (!tcp_inspect_response(s, s->rep, AN_RES_INSPECT))
						break;
					UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_INSPECT);
				}

				if (ana_list & AN_RES_WAIT_HTTP) {
					if (!http_wait_for_response(s, s->rep, AN_RES_WAIT_HTTP))
						break;
					UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_WAIT_HTTP);
				}

				if (ana_list & AN_RES_STORE_RULES) {
					if (!process_store_rules(s, s->rep, AN_RES_STORE_RULES))
						break;
					UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_STORE_RULES);
				}

				if (ana_list & AN_RES_HTTP_PROCESS_BE) {
					if (!http_process_res_common(s, s->rep, AN_RES_HTTP_PROCESS_BE, s->be))
						break;
					UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_HTTP_PROCESS_BE);
				}

				if (ana_list & AN_RES_HTTP_XFER_BODY) {
					if (!http_response_forward_body(s, s->rep, AN_RES_HTTP_XFER_BODY))
						break;
					UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_HTTP_XFER_BODY);
				}
				break;
			}
		}

		rp_cons_last = s->si[0].state;
		rp_prod_last = s->si[1].state;
		rpf_last = s->rep->flags;

		if ((s->rep->flags ^ flags) & CF_MASK_STATIC)
			goto resync_response;
	}

	/* maybe someone has added some request analysers, so we must check and loop */
	if (s->req->analysers & ~req_ana_back)
		goto resync_request;

	if ((s->req->flags & ~rqf_last) & CF_MASK_ANALYSER)
		goto resync_request;

	/* FIXME: here we should call protocol handlers which rely on
	 * both buffers.
	 */


	/*
	 * Now we propagate unhandled errors to the session. Normally
	 * we're just in a data phase here since it means we have not
	 * seen any analyser who could set an error status.
	 */
	srv = objt_server(s->target);
	if (unlikely(!(s->flags & SN_ERR_MASK))) {
		if (s->req->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
			/* Report it if the client got an error or a read timeout expired */
			s->req->analysers = 0;
			if (s->req->flags & CF_READ_ERROR) {
				s->be->be_counters.cli_aborts++;
				s->fe->fe_counters.cli_aborts++;
				if (srv)
					srv->counters.cli_aborts++;
				s->flags |= SN_ERR_CLICL;
			}
			else if (s->req->flags & CF_READ_TIMEOUT) {
				s->be->be_counters.cli_aborts++;
				s->fe->fe_counters.cli_aborts++;
				if (srv)
					srv->counters.cli_aborts++;
				s->flags |= SN_ERR_CLITO;
			}
			else if (s->req->flags & CF_WRITE_ERROR) {
				s->be->be_counters.srv_aborts++;
				s->fe->fe_counters.srv_aborts++;
				if (srv)
					srv->counters.srv_aborts++;
				s->flags |= SN_ERR_SRVCL;
			}
			else {
				s->be->be_counters.srv_aborts++;
				s->fe->fe_counters.srv_aborts++;
				if (srv)
					srv->counters.srv_aborts++;
				s->flags |= SN_ERR_SRVTO;
			}
			sess_set_term_flags(s);
		}
		else if (s->rep->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
			/* Report it if the server got an error or a read timeout expired */
			s->rep->analysers = 0;
			if (s->rep->flags & CF_READ_ERROR) {
				s->be->be_counters.srv_aborts++;
				s->fe->fe_counters.srv_aborts++;
				if (srv)
					srv->counters.srv_aborts++;
				s->flags |= SN_ERR_SRVCL;
			}
			else if (s->rep->flags & CF_READ_TIMEOUT) {
				s->be->be_counters.srv_aborts++;
				s->fe->fe_counters.srv_aborts++;
				if (srv)
					srv->counters.srv_aborts++;
				s->flags |= SN_ERR_SRVTO;
			}
			else if (s->rep->flags & CF_WRITE_ERROR) {
				s->be->be_counters.cli_aborts++;
				s->fe->fe_counters.cli_aborts++;
				if (srv)
					srv->counters.cli_aborts++;
				s->flags |= SN_ERR_CLICL;
			}
			else {
				s->be->be_counters.cli_aborts++;
				s->fe->fe_counters.cli_aborts++;
				if (srv)
					srv->counters.cli_aborts++;
				s->flags |= SN_ERR_CLITO;
			}
			sess_set_term_flags(s);
		}
	}

	/*
	 * Here we take care of forwarding unhandled data. This also includes
	 * connection establishments and shutdown requests.
	 */


	/* If noone is interested in analysing data, it's time to forward
	 * everything. We configure the buffer to forward indefinitely.
	 * Note that we're checking CF_SHUTR_NOW as an indication of a possible
	 * recent call to channel_abort().
	 */
	if (!s->req->analysers &&
	    !(s->req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
	    (s->req->prod->state >= SI_ST_EST) &&
	    (s->req->to_forward != CHN_INFINITE_FORWARD)) {
		/* This buffer is freewheeling, there's no analyser
		 * attached to it. If any data are left in, we'll permit them to
		 * move.
		 */
		channel_auto_read(s->req);
		channel_auto_connect(s->req);
		channel_auto_close(s->req);
		buffer_flush(s->req->buf);

		/* We'll let data flow between the producer (if still connected)
		 * to the consumer (which might possibly not be connected yet).
		 */
		if (!(s->req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
			channel_forward(s->req, CHN_INFINITE_FORWARD);
	}

	/* check if it is wise to enable kernel splicing to forward request data */
	if (!(s->req->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
	    s->req->to_forward &&
	    (global.tune.options & GTUNE_USE_SPLICE) &&
	    (s->si[0].conn->xprt && s->si[0].conn->xprt->rcv_pipe && s->si[0].conn->xprt->snd_pipe) &&
	    (s->si[1].conn->xprt && s->si[1].conn->xprt->rcv_pipe && s->si[1].conn->xprt->snd_pipe) &&
	    (pipes_used < global.maxpipes) &&
	    (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_REQ) ||
	     (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
	      (s->req->flags & CF_STREAMER_FAST)))) {
		s->req->flags |= CF_KERN_SPLICING;
	}

	/* reflect what the L7 analysers have seen last */
	rqf_last = s->req->flags;

	/*
	 * Now forward all shutdown requests between both sides of the buffer
	 */

	/* first, let's check if the request buffer needs to shutdown(write), which may
	 * happen either because the input is closed or because we want to force a close
	 * once the server has begun to respond.
	 */
	if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
		     (CF_AUTO_CLOSE|CF_SHUTR)))
			channel_shutw_now(s->req);

	/* shutdown(write) pending */
	if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
		     channel_is_empty(s->req)))
		si_shutw(s->req->cons);

	/* shutdown(write) done on server side, we must stop the client too */
	if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW &&
		     !s->req->analysers))
		channel_shutr_now(s->req);

	/* shutdown(read) pending */
	if (unlikely((s->req->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
		if (s->req->prod->flags & SI_FL_NOHALF)
			s->req->prod->flags |= SI_FL_NOLINGER;
		si_shutr(s->req->prod);
	}

	/* it's possible that an upper layer has requested a connection setup or abort.
	 * There are 2 situations where we decide to establish a new connection :
	 *  - there are data scheduled for emission in the buffer
	 *  - the CF_AUTO_CONNECT flag is set (active connection)
	 */
	if (s->req->cons->state == SI_ST_INI) {
		if (!(s->req->flags & CF_SHUTW)) {
			if ((s->req->flags & CF_AUTO_CONNECT) || !channel_is_empty(s->req)) {
				/* If we have an applet without a connect method, we immediately
				 * switch to the connected state, otherwise we perform a connection
				 * request.
				 */
				s->req->cons->state = SI_ST_REQ; /* new connection requested */
				s->req->cons->conn_retries = s->be->conn_retries;
				if (unlikely(obj_type(s->req->cons->conn->target) == OBJ_TYPE_APPLET &&
					     !(si_ctrl(s->req->cons) && si_ctrl(s->req->cons)->connect))) {
					s->req->cons->state = SI_ST_EST; /* connection established */
					s->rep->flags |= CF_READ_ATTACHED; /* producer is now attached */
					s->req->wex = TICK_ETERNITY;
				}
			}
		}
		else {
			s->req->cons->state = SI_ST_CLO; /* shutw+ini = abort */
			channel_shutw_now(s->req);        /* fix buffer flags upon abort */
			channel_shutr_now(s->rep);
		}
	}


	/* we may have a pending connection request, or a connection waiting
	 * for completion.
	 */
	if (s->si[1].state >= SI_ST_REQ && s->si[1].state < SI_ST_CON) {
		do {
			/* nb: step 1 might switch from QUE to ASS, but we first want
			 * to give a chance to step 2 to perform a redirect if needed.
			 */
			if (s->si[1].state != SI_ST_REQ)
				sess_update_stream_int(s, &s->si[1]);
			if (s->si[1].state == SI_ST_REQ)
				sess_prepare_conn_req(s, &s->si[1]);

			srv = objt_server(s->target);
			if (s->si[1].state == SI_ST_ASS && srv && srv->rdr_len && (s->flags & SN_REDIRECTABLE))
				perform_http_redirect(s, &s->si[1]);
		} while (s->si[1].state == SI_ST_ASS);

		/* Now we can add the server name to a header (if requested) */
		/* check for HTTP mode and proxy server_name_hdr_name != NULL */
		if ((s->flags & SN_BE_ASSIGNED) &&
		    (s->be->mode == PR_MODE_HTTP) &&
		    (s->be->server_id_hdr_name != NULL)) {
			http_send_name_header(&s->txn, s->be, objt_server(s->target)->id);
		}
	}

	/* Benchmarks have shown that it's optimal to do a full resync now */
	if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS)
		goto resync_stream_interface;

	/* otherwise we want to check if we need to resync the req buffer or not */
	if ((s->req->flags ^ rqf_last) & CF_MASK_STATIC)
		goto resync_request;

	/* perform output updates to the response buffer */

	/* If noone is interested in analysing data, it's time to forward
	 * everything. We configure the buffer to forward indefinitely.
	 * Note that we're checking CF_SHUTR_NOW as an indication of a possible
	 * recent call to channel_abort().
	 */
	if (!s->rep->analysers &&
	    !(s->rep->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
	    (s->rep->prod->state >= SI_ST_EST) &&
	    (s->rep->to_forward != CHN_INFINITE_FORWARD)) {
		/* This buffer is freewheeling, there's no analyser
		 * attached to it. If any data are left in, we'll permit them to
		 * move.
		 */
		channel_auto_read(s->rep);
		channel_auto_close(s->rep);
		buffer_flush(s->rep->buf);

		/* We'll let data flow between the producer (if still connected)
		 * to the consumer.
		 */
		if (!(s->rep->flags & (CF_SHUTR|CF_SHUTW_NOW)))
			channel_forward(s->rep, CHN_INFINITE_FORWARD);

		/* if we have no analyser anymore in any direction and have a
		 * tunnel timeout set, use it now.
		 */
		if (!s->req->analysers && s->be->timeout.tunnel) {
			s->req->rto = s->req->wto = s->rep->rto = s->rep->wto =
				s->be->timeout.tunnel;
			s->req->rex = s->req->wex = s->rep->rex = s->rep->wex =
				tick_add(now_ms, s->be->timeout.tunnel);
		}
	}

	/* check if it is wise to enable kernel splicing to forward response data */
	if (!(s->rep->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
	    s->rep->to_forward &&
	    (global.tune.options & GTUNE_USE_SPLICE) &&
	    (s->si[0].conn->xprt && s->si[0].conn->xprt->rcv_pipe && s->si[0].conn->xprt->snd_pipe) &&
	    (s->si[1].conn->xprt && s->si[1].conn->xprt->rcv_pipe && s->si[1].conn->xprt->snd_pipe) &&
	    (pipes_used < global.maxpipes) &&
	    (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_RTR) ||
	     (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
	      (s->rep->flags & CF_STREAMER_FAST)))) {
		s->rep->flags |= CF_KERN_SPLICING;
	}

	/* reflect what the L7 analysers have seen last */
	rpf_last = s->rep->flags;

	/*
	 * Now forward all shutdown requests between both sides of the buffer
	 */

	/*
	 * FIXME: this is probably where we should produce error responses.
	 */

	/* first, let's check if the response buffer needs to shutdown(write) */
	if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
		     (CF_AUTO_CLOSE|CF_SHUTR)))
		channel_shutw_now(s->rep);

	/* shutdown(write) pending */
	if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
		     channel_is_empty(s->rep)))
		si_shutw(s->rep->cons);

	/* shutdown(write) done on the client side, we must stop the server too */
	if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW) &&
	    !s->rep->analysers)
		channel_shutr_now(s->rep);

	/* shutdown(read) pending */
	if (unlikely((s->rep->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
		if (s->rep->prod->flags & SI_FL_NOHALF)
			s->rep->prod->flags |= SI_FL_NOLINGER;
		si_shutr(s->rep->prod);
	}

	if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS)
		goto resync_stream_interface;

	if (s->req->flags != rqf_last)
		goto resync_request;

	if ((s->rep->flags ^ rpf_last) & CF_MASK_STATIC)
		goto resync_response;

	/* we're interested in getting wakeups again */
	s->req->prod->flags &= ~SI_FL_DONT_WAKE;
	s->req->cons->flags &= ~SI_FL_DONT_WAKE;

	/* This is needed only when debugging is enabled, to indicate
	 * client-side or server-side close. Please note that in the unlikely
	 * event where both sides would close at once, the sequence is reported
	 * on the server side first.
	 */
	if (unlikely((global.mode & MODE_DEBUG) &&
		     (!(global.mode & MODE_QUIET) ||
		      (global.mode & MODE_VERBOSE)))) {
		if (s->si[1].state == SI_ST_CLO &&
		    s->si[1].prev_state == SI_ST_EST) {
			chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
				      s->uniq_id, s->be->id,
				      (unsigned short)s->si[0].conn->t.sock.fd,
				      (unsigned short)s->si[1].conn->t.sock.fd);
			if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
		}

		if (s->si[0].state == SI_ST_CLO &&
		    s->si[0].prev_state == SI_ST_EST) {
			chunk_printf(&trash, "%08x:%s.clicls[%04x:%04x]\n",
				      s->uniq_id, s->be->id,
				      (unsigned short)s->si[0].conn->t.sock.fd,
				      (unsigned short)s->si[1].conn->t.sock.fd);
			if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
		}
	}

	if (likely((s->rep->cons->state != SI_ST_CLO) ||
		   (s->req->cons->state > SI_ST_INI && s->req->cons->state < SI_ST_CLO))) {

		if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
			session_process_counters(s);

		if (s->rep->cons->state == SI_ST_EST && obj_type(s->rep->cons->conn->target) != OBJ_TYPE_APPLET)
			si_update(s->rep->cons);

		if (s->req->cons->state == SI_ST_EST && obj_type(s->req->cons->conn->target) != OBJ_TYPE_APPLET)
			si_update(s->req->cons);

		s->req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
		s->rep->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
		s->si[0].prev_state = s->si[0].state;
		s->si[1].prev_state = s->si[1].state;
		s->si[0].flags &= ~(SI_FL_ERR|SI_FL_EXP);
		s->si[1].flags &= ~(SI_FL_ERR|SI_FL_EXP);

		/* Trick: if a request is being waiting for the server to respond,
		 * and if we know the server can timeout, we don't want the timeout
		 * to expire on the client side first, but we're still interested
		 * in passing data from the client to the server (eg: POST). Thus,
		 * we can cancel the client's request timeout if the server's
		 * request timeout is set and the server has not yet sent a response.
		 */

		if ((s->rep->flags & (CF_AUTO_CLOSE|CF_SHUTR)) == 0 &&
		    (tick_isset(s->req->wex) || tick_isset(s->rep->rex))) {
			s->req->flags |= CF_READ_NOEXP;
			s->req->rex = TICK_ETERNITY;
		}

		/* Call the stream interfaces' I/O handlers when embedded.
		 * Note that this one may wake the task up again.
		 */
		if (obj_type(s->req->cons->conn->target) == OBJ_TYPE_APPLET ||
		    obj_type(s->rep->cons->conn->target) == OBJ_TYPE_APPLET) {
			if (objt_applet(s->req->cons->conn->target))
				objt_applet(s->req->cons->conn->target)->fct(s->req->cons);
			if (objt_applet(s->rep->cons->conn->target))
				objt_applet(s->rep->cons->conn->target)->fct(s->rep->cons);
			if (task_in_rq(t)) {
				/* If we woke up, we don't want to requeue the
				 * task to the wait queue, but rather requeue
				 * it into the runqueue ASAP.
				 */
				t->expire = TICK_ETERNITY;
				return t;
			}
		}

	update_exp_and_leave:
		t->expire = tick_first(tick_first(s->req->rex, s->req->wex),
				       tick_first(s->rep->rex, s->rep->wex));
		if (s->req->analysers)
			t->expire = tick_first(t->expire, s->req->analyse_exp);

		if (s->si[0].exp)
			t->expire = tick_first(t->expire, s->si[0].exp);

		if (s->si[1].exp)
			t->expire = tick_first(t->expire, s->si[1].exp);

#ifdef DEBUG_FULL
		fprintf(stderr,
			"[%u] queuing with exp=%u req->rex=%u req->wex=%u req->ana_exp=%u"
			" rep->rex=%u rep->wex=%u, si[0].exp=%u, si[1].exp=%u, cs=%d, ss=%d\n",
			now_ms, t->expire, s->req->rex, s->req->wex, s->req->analyse_exp,
			s->rep->rex, s->rep->wex, s->si[0].exp, s->si[1].exp, s->si[0].state, s->si[1].state);
#endif

#ifdef DEBUG_DEV
		/* this may only happen when no timeout is set or in case of an FSM bug */
		if (!tick_isset(t->expire))
			ABORT_NOW();
#endif
		return t; /* nothing more to do */
	}

	s->fe->feconn--;
	if (s->flags & SN_BE_ASSIGNED)
		s->be->beconn--;
	if (!(s->listener->options & LI_O_UNLIMITED))
		actconn--;
	jobs--;
	s->listener->nbconn--;
	if (s->listener->state == LI_FULL)
		resume_listener(s->listener);

	/* Dequeues all of the listeners waiting for a resource */
	if (!LIST_ISEMPTY(&global_listener_queue))
		dequeue_all_listeners(&global_listener_queue);

	if (!LIST_ISEMPTY(&s->fe->listener_queue) &&
	    (!s->fe->fe_sps_lim || freq_ctr_remain(&s->fe->fe_sess_per_sec, s->fe->fe_sps_lim, 0) > 0))
		dequeue_all_listeners(&s->fe->listener_queue);

	if (unlikely((global.mode & MODE_DEBUG) &&
		     (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
		chunk_printf(&trash, "%08x:%s.closed[%04x:%04x]\n",
			      s->uniq_id, s->be->id,
			      (unsigned short)s->req->prod->conn->t.sock.fd,
			      (unsigned short)s->req->cons->conn->t.sock.fd);
		if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
	}

	s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
	session_process_counters(s);

	if (s->txn.status) {
		int n;

		n = s->txn.status / 100;
		if (n < 1 || n > 5)
			n = 0;

		if (s->fe->mode == PR_MODE_HTTP)
			s->fe->fe_counters.p.http.rsp[n]++;

		if ((s->flags & SN_BE_ASSIGNED) &&
		    (s->be->mode == PR_MODE_HTTP))
			s->be->be_counters.p.http.rsp[n]++;
	}

	/* let's do a final log if we need it */
	if (s->logs.logwait &&
	    !(s->flags & SN_MONITOR) &&
	    (!(s->fe->options & PR_O_NULLNOLOG) || s->req->total)) {
		s->do_log(s);
	}

	/* the task MUST not be in the run queue anymore */
	session_free(s);
	task_delete(t);
	task_free(t);
	return NULL;
}

/*
 * This function adjusts sess->srv_conn and maintains the previous and new
 * server's served session counts. Setting newsrv to NULL is enough to release
 * current connection slot. This function also notifies any LB algo which might
 * expect to be informed about any change in the number of active sessions on a
 * server.
 */
void sess_change_server(struct session *sess, struct server *newsrv)
{
	if (sess->srv_conn == newsrv)
		return;

	if (sess->srv_conn) {
		sess->srv_conn->served--;
		if (sess->srv_conn->proxy->lbprm.server_drop_conn)
			sess->srv_conn->proxy->lbprm.server_drop_conn(sess->srv_conn);
		session_del_srv_conn(sess);
	}

	if (newsrv) {
		newsrv->served++;
		if (newsrv->proxy->lbprm.server_take_conn)
			newsrv->proxy->lbprm.server_take_conn(newsrv);
		session_add_srv_conn(sess, newsrv);
	}
}

/* Handle server-side errors for default protocols. It is called whenever a a
 * connection setup is aborted or a request is aborted in queue. It sets the
 * session termination flags so that the caller does not have to worry about
 * them. It's installed as ->srv_error for the server-side stream_interface.
 */
void default_srv_error(struct session *s, struct stream_interface *si)
{
	int err_type = si->err_type;
	int err = 0, fin = 0;

	if (err_type & SI_ET_QUEUE_ABRT) {
		err = SN_ERR_CLICL;
		fin = SN_FINST_Q;
	}
	else if (err_type & SI_ET_CONN_ABRT) {
		err = SN_ERR_CLICL;
		fin = SN_FINST_C;
	}
	else if (err_type & SI_ET_QUEUE_TO) {
		err = SN_ERR_SRVTO;
		fin = SN_FINST_Q;
	}
	else if (err_type & SI_ET_QUEUE_ERR) {
		err = SN_ERR_SRVCL;
		fin = SN_FINST_Q;
	}
	else if (err_type & SI_ET_CONN_TO) {
		err = SN_ERR_SRVTO;
		fin = SN_FINST_C;
	}
	else if (err_type & SI_ET_CONN_ERR) {
		err = SN_ERR_SRVCL;
		fin = SN_FINST_C;
	}
	else /* SI_ET_CONN_OTHER and others */ {
		err = SN_ERR_INTERNAL;
		fin = SN_FINST_C;
	}

	if (!(s->flags & SN_ERR_MASK))
		s->flags |= err;
	if (!(s->flags & SN_FINST_MASK))
		s->flags |= fin;
}

/* kill a session and set the termination flags to <why> (one of SN_ERR_*) */
void session_shutdown(struct session *session, int why)
{
	if (session->req->flags & (CF_SHUTW|CF_SHUTW_NOW))
		return;

	channel_shutw_now(session->req);
	channel_shutr_now(session->rep);
	session->task->nice = 1024;
	if (!(session->flags & SN_ERR_MASK))
		session->flags |= why;
	task_wakeup(session->task, TASK_WOKEN_OTHER);
}

/************************************************************************/
/*           All supported ACL keywords must be declared here.          */
/************************************************************************/

/* set temp integer to the General Purpose Counter 0 value in the stksess entry <ts> */
static int
acl_fetch_get_gpc0(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, gpc0);
	}
	return 1;
}

/* set temp integer to the General Purpose Counter 0 value from the session's tracked
 * frontend counters.
 */
static int
acl_fetch_sc1_get_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;
	return acl_fetch_get_gpc0(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the General Purpose Counter 0 value from the session's tracked
 * backend counters.
 */
static int
acl_fetch_sc2_get_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;
	return acl_fetch_get_gpc0(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the General Purpose Counter 0 value from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_get_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_get_gpc0(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* Increment the General Purpose Counter 0 value in the stksess entry <ts> and
 * return it into temp integer.
 */
static int
acl_fetch_inc_gpc0(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = ++stktable_data_cast(ptr, gpc0);
	}
	return 1;
}

/* Increment the General Purpose Counter 0 value from the session's tracked
 * frontend counters and return it into temp integer.
 */
static int
acl_fetch_sc1_inc_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;
	return acl_fetch_inc_gpc0(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* Increment the General Purpose Counter 0 value from the session's tracked
 * backend counters and return it into temp integer.
 */
static int
acl_fetch_sc2_inc_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;
	return acl_fetch_inc_gpc0(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* Increment the General Purpose Counter 0 value from the session's source
 * address in the table pointed to by expr, and return it into temp integer.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_inc_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_inc_gpc0(&px->table, smp, stktable_update_key(&px->table, key));
}

/* Clear the General Purpose Counter 0 value in the stksess entry <ts> and
 * return its previous value into temp integer.
 */
static int
acl_fetch_clr_gpc0(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, gpc0);
		stktable_data_cast(ptr, gpc0) = 0;
	}
	return 1;
}

/* Clear the General Purpose Counter 0 value from the session's tracked
 * frontend counters and return its previous value into temp integer.
 */
static int
acl_fetch_sc1_clr_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;
	return acl_fetch_clr_gpc0(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* Clear the General Purpose Counter 0 value from the session's tracked
 * backend counters and return its previous value into temp integer.
 */
static int
acl_fetch_sc2_clr_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;
	return acl_fetch_clr_gpc0(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* Clear the General Purpose Counter 0 value from the session's source address
 * in the table pointed to by expr, and return its previous value into temp integer.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_clr_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_clr_gpc0(&px->table, smp, stktable_update_key(&px->table, key));
}

/* set temp integer to the cumulated number of connections in the stksess entry <ts> */
static int
acl_fetch_conn_cnt(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_CONN_CNT);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, conn_cnt);
	}
	return 1;
}

/* set temp integer to the cumulated number of connections from the session's tracked FE counters */
static int
acl_fetch_sc1_conn_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_conn_cnt(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the cumulated number of connections from the session's tracked BE counters */
static int
acl_fetch_sc2_conn_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_conn_cnt(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the cumulated number of connections from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_conn_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_conn_cnt(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the connection rate in the stksess entry <ts> over the configured period */
static int
acl_fetch_conn_rate(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_CONN_RATE);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
					       table->data_arg[STKTABLE_DT_CONN_RATE].u);
	}
	return 1;
}

/* set temp integer to the connection rate from the session's tracked FE counters over
 * the configured period.
 */
static int
acl_fetch_sc1_conn_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_conn_rate(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the connection rate from the session's tracked BE counters over
 * the configured period.
 */
static int
acl_fetch_sc2_conn_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_conn_rate(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the connection rate from the session's source address in the
 * table pointed to by expr, over the configured period.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_conn_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_conn_rate(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the number of connections from the session's source address
 * in the table pointed to by expr, after updating it.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_updt_conn_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	struct stksess *ts;
	struct stktable_key *key;
	void *ptr;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;

	if ((ts = stktable_update_key(&px->table, key)) == NULL)
		/* entry does not exist and could not be created */
		return 0;

	ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT);
	if (!ptr)
		return 0; /* parameter not stored in this table */

	smp->type = SMP_T_UINT;
	smp->data.uint = ++stktable_data_cast(ptr, conn_cnt);
	smp->flags = SMP_F_VOL_TEST;
	return 1;
}

/* set temp integer to the number of concurrent connections in the stksess entry <ts> */
static int
acl_fetch_conn_cur(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;

	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_CONN_CUR);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, conn_cur);
	}
	return 1;
}

/* set temp integer to the number of concurrent connections from the session's tracked FE counters */
static int
acl_fetch_sc1_conn_cur(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_conn_cur(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the number of concurrent connections from the session's tracked BE counters */
static int
acl_fetch_sc2_conn_cur(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_conn_cur(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the number of concurrent connections from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_conn_cur(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_conn_cur(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the cumulated number of sessions in the stksess entry <ts> */
static int
acl_fetch_sess_cnt(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_SESS_CNT);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, sess_cnt);
	}
	return 1;
}

/* set temp integer to the cumulated number of sessions from the session's tracked FE counters */
static int
acl_fetch_sc1_sess_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_sess_cnt(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the cumulated number of sessions from the session's tracked BE counters */
static int
acl_fetch_sc2_sess_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_sess_cnt(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the cumulated number of session from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_sess_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_sess_cnt(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the session rate in the stksess entry <ts> over the configured period */
static int
acl_fetch_sess_rate(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_SESS_RATE);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate),
					       table->data_arg[STKTABLE_DT_SESS_RATE].u);
	}
	return 1;
}

/* set temp integer to the session rate from the session's tracked FE counters over
 * the configured period.
 */
static int
acl_fetch_sc1_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_sess_rate(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the session rate from the session's tracked BE counters over
 * the configured period.
 */
static int
acl_fetch_sc2_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_sess_rate(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the session rate from the session's source address in the
 * table pointed to by expr, over the configured period.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_sess_rate(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the cumulated number of sessions in the stksess entry <ts> */
static int
acl_fetch_http_req_cnt(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_HTTP_REQ_CNT);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, http_req_cnt);
	}
	return 1;
}

/* set temp integer to the cumulated number of sessions from the session's tracked FE counters */
static int
acl_fetch_sc1_http_req_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                           const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_http_req_cnt(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the cumulated number of sessions from the session's tracked BE counters */
static int
acl_fetch_sc2_http_req_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                           const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_http_req_cnt(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the cumulated number of session from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_http_req_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                           const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_http_req_cnt(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the session rate in the stksess entry <ts> over the configured period */
static int
acl_fetch_http_req_rate(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_HTTP_REQ_RATE);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
					       table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u);
	}
	return 1;
}

/* set temp integer to the session rate from the session's tracked FE counters over
 * the configured period.
 */
static int
acl_fetch_sc1_http_req_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_http_req_rate(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the session rate from the session's tracked BE counters over
 * the configured period.
 */
static int
acl_fetch_sc2_http_req_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_http_req_rate(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the session rate from the session's source address in the
 * table pointed to by expr, over the configured period.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_http_req_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_http_req_rate(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the cumulated number of sessions in the stksess entry <ts> */
static int
acl_fetch_http_err_cnt(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_HTTP_ERR_CNT);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, http_err_cnt);
	}
	return 1;
}

/* set temp integer to the cumulated number of sessions from the session's tracked FE counters */
static int
acl_fetch_sc1_http_err_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                           const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_http_err_cnt(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the cumulated number of sessions from the session's tracked BE counters */
static int
acl_fetch_sc2_http_err_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                           const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_http_err_cnt(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the cumulated number of session from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_http_err_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                           const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_http_err_cnt(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the session rate in the stksess entry <ts> over the configured period */
static int
acl_fetch_http_err_rate(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_HTTP_ERR_RATE);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
					       table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u);
	}
	return 1;
}

/* set temp integer to the session rate from the session's tracked FE counters over
 * the configured period.
 */
static int
acl_fetch_sc1_http_err_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_http_err_rate(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the session rate from the session's tracked BE counters over
 * the configured period.
 */
static int
acl_fetch_sc2_http_err_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_http_err_rate(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the session rate from the session's source address in the
 * table pointed to by expr, over the configured period.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_http_err_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_http_err_rate(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the number of kbytes received from clients matching the stksess entry <ts> */
static int
acl_fetch_kbytes_in(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;

	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_BYTES_IN_CNT);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, bytes_in_cnt) >> 10;
	}
	return 1;
}

/* set temp integer to the number of kbytes received from clients according to the
 * session's tracked FE counters.
 */
static int
acl_fetch_sc1_kbytes_in(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_kbytes_in(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the number of kbytes received from clients according to the
 * session's tracked BE counters.
 */
static int
acl_fetch_sc2_kbytes_in(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_kbytes_in(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the number of kbytes received from the session's source
 * address in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_kbytes_in(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                       const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_kbytes_in(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the bytes rate from clients in the stksess entry <ts> over the
 * configured period.
 */
static int
acl_fetch_bytes_in_rate(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_BYTES_IN_RATE);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
					       table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u);
	}
	return 1;
}

/* set temp integer to the bytes rate from clients from the session's tracked FE
 * counters over the configured period.
 */
static int
acl_fetch_sc1_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_bytes_in_rate(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the bytes rate from clients from the session's tracked BE
 * counters over the configured period.
 */
static int
acl_fetch_sc2_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_bytes_in_rate(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the bytes rate from clients from the session's source address
 * in the table pointed to by expr, over the configured period.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                            const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_bytes_in_rate(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the number of kbytes sent to clients matching the stksess entry <ts> */
static int
acl_fetch_kbytes_out(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;

	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_BYTES_OUT_CNT);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = stktable_data_cast(ptr, bytes_out_cnt) >> 10;
	}
	return 1;
}

/* set temp integer to the number of kbytes sent to clients according to the session's
 * tracked FE counters.
 */
static int
acl_fetch_sc1_kbytes_out(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                         const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_kbytes_out(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the number of kbytes sent to clients according to the session's
 * tracked BE counters.
 */
static int
acl_fetch_sc2_kbytes_out(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                         const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_kbytes_out(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the number of kbytes sent to the session's source address in
 * the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_kbytes_out(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                         const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_kbytes_out(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the bytes rate to clients in the stksess entry <ts> over the
 * configured period.
 */
static int
acl_fetch_bytes_out_rate(struct stktable *table, struct sample *smp, struct stksess *ts)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = 0;
	if (ts != NULL) {
		void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_BYTES_OUT_RATE);
		if (!ptr)
			return 0; /* parameter not stored */
		smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
					       table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u);
	}
	return 1;
}

/* set temp integer to the bytes rate to clients from the session's tracked FE counters
 * over the configured period.
 */
static int
acl_fetch_sc1_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                             const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr1_entry)
		return 0;

	return acl_fetch_bytes_out_rate(l4->stkctr1_table, smp, l4->stkctr1_entry);
}

/* set temp integer to the bytes rate to clients from the session's tracked BE counters
 * over the configured period.
 */
static int
acl_fetch_sc2_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                             const struct arg *args, struct sample *smp)
{
	if (!l4->stkctr2_entry)
		return 0;

	return acl_fetch_bytes_out_rate(l4->stkctr2_table, smp, l4->stkctr2_entry);
}

/* set temp integer to the bytes rate to client from the session's source address in
 * the table pointed to by expr, over the configured period.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_src_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                             const struct arg *args, struct sample *smp)
{
	struct stktable_key *key;

	key = addr_to_stktable_key(&l4->si[0].conn->addr.from);
	if (!key)
		return 0;

	px = args->data.prx;
	return acl_fetch_bytes_out_rate(&px->table, smp, stktable_lookup_key(&px->table, key));
}

/* set temp integer to the number of used entries in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_table_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                    const struct arg *args, struct sample *smp)
{
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = args->data.prx->table.current;
	return 1;
}

/* set temp integer to the number of free entries in the table pointed to by expr.
 * Accepts exactly 1 argument of type table.
 */
static int
acl_fetch_table_avl(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                    const struct arg *args, struct sample *smp)
{
	px = args->data.prx;
	smp->flags = SMP_F_VOL_TEST;
	smp->type = SMP_T_UINT;
	smp->data.uint = px->table.size - px->table.current;
	return 1;
}

/* Note: must not be declared <const> as its list will be overwritten.
 * Please take care of keeping this list alphabetically sorted.
 */
static struct acl_kw_list acl_kws = {{ },{
	{ "sc1_bytes_in_rate",  acl_parse_int,   acl_fetch_sc1_bytes_in_rate,  acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_bytes_out_rate", acl_parse_int,   acl_fetch_sc1_bytes_out_rate, acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_clr_gpc0",       acl_parse_int,   acl_fetch_sc1_clr_gpc0,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_conn_cnt",       acl_parse_int,   acl_fetch_sc1_conn_cnt,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_conn_cur",       acl_parse_int,   acl_fetch_sc1_conn_cur,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_conn_rate",      acl_parse_int,   acl_fetch_sc1_conn_rate,      acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_get_gpc0",       acl_parse_int,   acl_fetch_sc1_get_gpc0,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_http_err_cnt",   acl_parse_int,   acl_fetch_sc1_http_err_cnt,   acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_http_err_rate",  acl_parse_int,   acl_fetch_sc1_http_err_rate,  acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_http_req_cnt",   acl_parse_int,   acl_fetch_sc1_http_req_cnt,   acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_http_req_rate",  acl_parse_int,   acl_fetch_sc1_http_req_rate,  acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_inc_gpc0",       acl_parse_int,   acl_fetch_sc1_inc_gpc0,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_kbytes_in",      acl_parse_int,   acl_fetch_sc1_kbytes_in,      acl_match_int, ACL_USE_TCP4_VOLATILE, 0 },
	{ "sc1_kbytes_out",     acl_parse_int,   acl_fetch_sc1_kbytes_out,     acl_match_int, ACL_USE_TCP4_VOLATILE, 0 },
	{ "sc1_sess_cnt",       acl_parse_int,   acl_fetch_sc1_sess_cnt,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc1_sess_rate",      acl_parse_int,   acl_fetch_sc1_sess_rate,      acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_bytes_in_rate",  acl_parse_int,   acl_fetch_sc2_bytes_in_rate,  acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_bytes_out_rate", acl_parse_int,   acl_fetch_sc2_bytes_out_rate, acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_clr_gpc0",       acl_parse_int,   acl_fetch_sc2_clr_gpc0,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_conn_cnt",       acl_parse_int,   acl_fetch_sc2_conn_cnt,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_conn_cur",       acl_parse_int,   acl_fetch_sc2_conn_cur,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_conn_rate",      acl_parse_int,   acl_fetch_sc2_conn_rate,      acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_get_gpc0",       acl_parse_int,   acl_fetch_sc2_get_gpc0,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_http_err_cnt",   acl_parse_int,   acl_fetch_sc2_http_err_cnt,   acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_http_err_rate",  acl_parse_int,   acl_fetch_sc2_http_err_rate,  acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_http_req_cnt",   acl_parse_int,   acl_fetch_sc2_http_req_cnt,   acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_http_req_rate",  acl_parse_int,   acl_fetch_sc2_http_req_rate,  acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_inc_gpc0",       acl_parse_int,   acl_fetch_sc2_inc_gpc0,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_kbytes_in",      acl_parse_int,   acl_fetch_sc2_kbytes_in,      acl_match_int, ACL_USE_TCP4_VOLATILE, 0 },
	{ "sc2_kbytes_out",     acl_parse_int,   acl_fetch_sc2_kbytes_out,     acl_match_int, ACL_USE_TCP4_VOLATILE, 0 },
	{ "sc2_sess_cnt",       acl_parse_int,   acl_fetch_sc2_sess_cnt,       acl_match_int, ACL_USE_NOTHING,       0 },
	{ "sc2_sess_rate",      acl_parse_int,   acl_fetch_sc2_sess_rate,      acl_match_int, ACL_USE_NOTHING,       0 },
	{ "src_bytes_in_rate",  acl_parse_int,   acl_fetch_src_bytes_in_rate,  acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_bytes_out_rate", acl_parse_int,   acl_fetch_src_bytes_out_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_clr_gpc0",       acl_parse_int,   acl_fetch_src_clr_gpc0,       acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_conn_cnt",       acl_parse_int,   acl_fetch_src_conn_cnt,       acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_conn_cur",       acl_parse_int,   acl_fetch_src_conn_cur,       acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_conn_rate",      acl_parse_int,   acl_fetch_src_conn_rate,      acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_get_gpc0",       acl_parse_int,   acl_fetch_src_get_gpc0,       acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_http_err_cnt",   acl_parse_int,   acl_fetch_src_http_err_cnt,   acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_http_err_rate",  acl_parse_int,   acl_fetch_src_http_err_rate,  acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_http_req_cnt",   acl_parse_int,   acl_fetch_src_http_req_cnt,   acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_http_req_rate",  acl_parse_int,   acl_fetch_src_http_req_rate,  acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_inc_gpc0",       acl_parse_int,   acl_fetch_src_inc_gpc0,       acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_kbytes_in",      acl_parse_int,   acl_fetch_src_kbytes_in,      acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_kbytes_out",     acl_parse_int,   acl_fetch_src_kbytes_out,     acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_sess_cnt",       acl_parse_int,   acl_fetch_src_sess_cnt,       acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_sess_rate",      acl_parse_int,   acl_fetch_src_sess_rate,      acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "src_updt_conn_cnt",  acl_parse_int,   acl_fetch_src_updt_conn_cnt,  acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) },
	{ "table_avl",          acl_parse_int,   acl_fetch_table_avl,          acl_match_int, ACL_USE_NOTHING,       ARG1(1,TAB) },
	{ "table_cnt",          acl_parse_int,   acl_fetch_table_cnt,          acl_match_int, ACL_USE_NOTHING,       ARG1(1,TAB) },
	{ NULL, NULL, NULL, NULL },
}};


/* Parse a "track-sc[12]" line starting with "track-sc[12]" in args[arg-1].
 * Returns the number of warnings emitted, or -1 in case of fatal errors. The
 * <prm> struct is fed with the table name if any. If unspecified, the caller
 * will assume that the current proxy's table is used.
 */
int parse_track_counters(char **args, int *arg,
			 int section_type, struct proxy *curpx,
			 struct track_ctr_prm *prm,
			 struct proxy *defpx, char **err)
{
	int sample_type = 0;

	/* parse the arguments of "track-sc[12]" before the condition in the
	 * following form :
	 *      track-sc[12] src [ table xxx ] [ if|unless ... ]
	 */
	while (args[*arg]) {
		if (strcmp(args[*arg], "src") == 0) {
			prm->type = STKTABLE_TYPE_IP;
			sample_type = 1;
		}
		else if (strcmp(args[*arg], "table") == 0) {
			if (!args[*arg + 1]) {
				memprintf(err, "missing table name");
				return -1;
			}
			/* we copy the table name for now, it will be resolved later */
			prm->table.n = strdup(args[*arg + 1]);
			(*arg)++;
		}
		else {
			/* unhandled keywords are handled by the caller */
			break;
		}
		(*arg)++;
	}

	if (!sample_type) {
		memprintf(err,
		          "tracking key not specified (found %s, only 'src' is supported)",
		          quote_arg(args[*arg]));
		return -1;
	}

	return 0;
}

__attribute__((constructor))
static void __session_init(void)
{
	acl_register_keywords(&acl_kws);
}

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