[CLEANUP] Move counters to dedicated structures

Move counters from "struct proxy" and "struct server"
to "struct pxcounters" and "struct svcounters".

This patch should make no functional change.
diff --git a/include/proto/proxy.h b/include/proto/proxy.h
index 0ad1e7f..f293b1b 100644
--- a/include/proto/proxy.h
+++ b/include/proto/proxy.h
@@ -66,9 +66,9 @@
 }
 
 /* increase the number of cumulated connections on the designated frontend */
-static void inline proxy_inc_fe_ctr(struct proxy *fe)
+static void inline proxy_inc_fe_ctr(struct listener *l, struct proxy *fe)
 {
-	fe->cum_feconn++;
+	fe->counters.cum_feconn++;
 	update_freq_ctr(&fe->fe_sess_per_sec, 1);
 	if (fe->fe_sess_per_sec.curr_ctr > fe->fe_sps_max)
 		fe->fe_sps_max = fe->fe_sess_per_sec.curr_ctr;
@@ -77,7 +77,7 @@
 /* increase the number of cumulated connections on the designated backend */
 static void inline proxy_inc_be_ctr(struct proxy *be)
 {
-	be->cum_beconn++;
+	be->counters.cum_beconn++;
 	update_freq_ctr(&be->be_sess_per_sec, 1);
 	if (be->be_sess_per_sec.curr_ctr > be->be_sps_max)
 		be->be_sps_max = be->be_sess_per_sec.curr_ctr;
diff --git a/include/proto/server.h b/include/proto/server.h
index 7479c2e..43d9216 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -38,7 +38,7 @@
 /* increase the number of cumulated connections on the designated server */
 static void inline srv_inc_sess_ctr(struct server *s)
 {
-	s->cum_sess++;
+	s->counters.cum_sess++;
 	update_freq_ctr(&s->sess_per_sec, 1);
 	if (s->sess_per_sec.curr_ctr > s->sps_max)
 		s->sps_max = s->sess_per_sec.curr_ctr;
diff --git a/include/types/protocols.h b/include/types/protocols.h
index 9247ef1..14aee79 100644
--- a/include/types/protocols.h
+++ b/include/types/protocols.h
@@ -76,6 +76,8 @@
  */
 struct listener {
 	int fd;				/* the listen socket */
+	char *name;			/* */
+	int luid;			/* listener universally unique ID, used for SNMP */
 	int state;			/* state: NEW, INIT, ASSIGNED, LISTEN, READY, FULL */
 	int options;			/* socket options : LI_O_* */
 	struct sockaddr_storage addr;	/* the address we listen to */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index ed632a2..432111b 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -37,6 +37,7 @@
 #include <types/acl.h>
 #include <types/backend.h>
 #include <types/buffers.h>
+#include <types/counters.h>
 #include <types/freq_ctr.h>
 #include <types/httperr.h>
 #include <types/log.h>
@@ -196,14 +197,11 @@
 	struct list pendconns;			/* pending connections with no server assigned yet */
 	int nbpend, nbpend_max;			/* number of pending connections with no server assigned yet */
 	int totpend;				/* total number of pending connections on this instance (for stats) */
-	unsigned int feconn, feconn_max;	/* # of active frontend sessions */
-	unsigned int beconn, beconn_max;	/* # of active backend sessions */
+	unsigned int feconn, beconn;		/* # of active frontend and backends sessions */
 	struct freq_ctr fe_sess_per_sec;	/* sessions per second on the frontend */
 	unsigned int fe_sps_max;		/* maximum of new sessions per second seen on the frontend */
 	struct freq_ctr be_sess_per_sec;	/* sessions per second on the backend */
 	unsigned int be_sps_max;		/* maximum of new sessions per second seen on the backend */
-	long long cum_feconn, cum_beconn;	/* cumulated number of processed sessions */
-	long long cum_lbconn;			/* cumulated number of sessions processed by load balancing */
 	unsigned int maxconn;			/* max # of active sessions on the frontend */
 	unsigned int fe_sps_lim;		/* limit on new sessions per second on the frontend */
 	unsigned int fullconn;			/* #conns on backend above which servers are used at full load */
@@ -219,12 +217,6 @@
 	unsigned down_time;			/* total time the proxy was down */
 	time_t last_change;			/* last time, when the state was changed */
 
-	long long failed_conns, failed_resp;	/* failed connect() and responses */
-	long long retries, redispatches;	/* retried and redispatched connections */
-	long long denied_req, denied_resp;	/* blocked requests/responses because of security concerns */
-	long long failed_req;			/* failed requests (eg: invalid or timeout) */
-	long long bytes_in;			/* number of bytes transferred from the client to the server */
-	long long bytes_out;			/* number of bytes transferred from the server to the client */
 	int conn_retries;			/* maximum number of connect retries */
 	int cap;				/* supported capabilities (PR_CAP_*) */
 	struct sockaddr_in source_addr;		/* the address to which we want to bind for connect() */
@@ -255,7 +247,7 @@
 	int check_len;				/* Length of the HTTP or SSL3 request */
 	struct chunk errmsg[HTTP_ERR_SIZE];	/* default or customized error messages for known errors */
 	int uuid;				/* universally unique proxy ID, used for SNMP */
-	int next_svid;				/* next server-id, used for SNMP */
+	int next_svid, next_lid;		/* next server-id and listener-id, used for SNMP */
 	unsigned int backlog;			/* force the frontend's listen backlog */
 	unsigned int bind_proc;			/* bitmask of processes using this proxy. 0 = all. */
 	struct error_snapshot invalid_req, invalid_rep; /* captures of last errors */
@@ -263,6 +255,8 @@
 	/* used only during configuration parsing */
 	int no_options;				/* PR_O_REDISP, PR_O_TRANSP, ... */
 	int no_options2;			/* PR_O2_* */
+
+	struct pxcounters counters;		/* statistics counters */
 };
 
 struct switching_rule {
diff --git a/include/types/server.h b/include/types/server.h
index 3304004..ddf5a46 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -30,6 +30,7 @@
 #include <common/mini-clist.h>
 
 #include <types/buffers.h>
+#include <types/counters.h>
 #include <types/freq_ctr.h>
 #include <types/port_range.h>
 #include <types/proxy.h>
@@ -119,24 +120,17 @@
 	struct eb_root *lb_tree;                /* we want to know in what tree the server is */
 	struct server *next_full;               /* next server in the temporary full list */
 
-	long long failed_checks, down_trans;	/* failed checks and up-down transitions */
 	unsigned down_time;			/* total time the server was down */
 	time_t last_change;			/* last time, when the state was changed */
 	struct timeval check_start;		/* last health check start time */
 	unsigned long check_duration;		/* time in ms took to finish last health check */
 	short check_status, check_code;		/* check result, check code */
 
-	long long failed_conns, failed_resp;	/* failed connect() and responses */
-	long long retries, redispatches;	/* retried and redispatched connections */
-	long long failed_secu;			/* blocked responses because of security concerns */
 	struct freq_ctr sess_per_sec;		/* sessions per second on this server */
 	unsigned int sps_max;			/* maximum of new sessions per second seen on this server */
-	long long cum_sess;			/* cumulated number of sessions really sent to this server */
-	long long cum_lbconn;			/* cumulated number of sessions directed by load balancing */
-
-	long long bytes_in;			/* number of bytes transferred from the client to the server */
-	long long bytes_out;			/* number of bytes transferred from the server to the client */
 	int puid;				/* proxy-unique server ID, used for SNMP */
+
+	struct srvcounters counters;		/* statistics counters */
 };
 
 
diff --git a/src/backend.c b/src/backend.c
index 39726ce..56b15d1 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -598,8 +598,8 @@
 			goto out;
 		}
 		else if (s->srv != s->prev_srv) {
-			s->be->cum_lbconn++;
-			s->srv->cum_lbconn++;
+			s->be->counters.cum_lbconn++;
+			s->srv->counters.cum_lbconn++;
 		}
 	}
 	else if (s->be->options & PR_O_HTTP_PROXY) {
@@ -749,11 +749,11 @@
 					s->txn.flags |= TX_CK_DOWN;
 				}
 				s->flags |= SN_REDISP;
-				s->prev_srv->redispatches++;
-				s->be->redispatches++;
+				s->prev_srv->counters.redispatches++;
+				s->be->counters.redispatches++;
 			} else {
-				s->prev_srv->retries++;
-				s->be->retries++;
+				s->prev_srv->counters.retries++;
+				s->be->counters.retries++;
 			}
 		}
 	}
@@ -906,8 +906,8 @@
 			t->req->cons->err_loc = t->srv;
 		}
 
-		t->srv->failed_conns++;
-		t->be->failed_conns++;
+		t->srv->counters.failed_conns++;
+		t->be->counters.failed_conns++;
 		return 1;
 
 	case SRV_STATUS_NOSRV:
@@ -917,7 +917,7 @@
 			t->req->cons->err_loc = NULL;
 		}
 
-		t->be->failed_conns++;
+		t->be->counters.failed_conns++;
 		return 1;
 
 	case SRV_STATUS_QUEUED:
@@ -936,8 +936,8 @@
 		if (t->srv)
 			srv_inc_sess_ctr(t->srv);
 		if (t->srv)
-			t->srv->failed_conns++;
-		t->be->failed_conns++;
+			t->srv->counters.failed_conns++;
+		t->be->counters.failed_conns++;
 
 		/* release other sessions waiting for this server */
 		if (may_dequeue_tasks(t->srv, t->be))
diff --git a/src/checks.c b/src/checks.c
index 723e693..a21386f 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -344,7 +344,7 @@
 		if (s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
 			set_backend_down(s->proxy);
 
-		s->down_trans++;
+		s->counters.down_trans++;
 
 		if (s->state & SRV_CHECKED)
 			for(srv = s->tracknext; srv; srv = srv->tracknext)
@@ -942,7 +942,7 @@
 		/* here, we have seen a failure */
 		if (s->health > s->rise) {
 			s->health--; /* still good */
-			s->failed_checks++;
+			s->counters.failed_checks++;
 		}
 		else
 			set_server_down(s);
@@ -1033,7 +1033,7 @@
 			/* failure or timeout detected */
 			if (s->health > s->rise) {
 				s->health--; /* still good */
-				s->failed_checks++;
+				s->counters.failed_checks++;
 			}
 			else
 				set_server_down(s);
diff --git a/src/client.c b/src/client.c
index ec768d8..fe29b4c 100644
--- a/src/client.c
+++ b/src/client.c
@@ -255,7 +255,7 @@
 		s->data_source = DATA_SRC_NONE;
 
 		s->uniq_id = totalconn;
-		proxy_inc_fe_ctr(p);	/* note: cum_beconn will be increased once assigned */
+		proxy_inc_fe_ctr(l, p);	/* note: cum_beconn will be increased once assigned */
 
 		txn = &s->txn;
 		txn->flags = 0;
@@ -488,8 +488,8 @@
 		}
 
 		p->feconn++;  /* beconn will be increased later */
-		if (p->feconn > p->feconn_max)
-			p->feconn_max = p->feconn;
+		if (p->feconn > p->counters.feconn_max)
+			p->counters.feconn_max = p->feconn;
 
 		actconn++;
 		totalconn++;
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 3e65ab7..41b2dd3 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -1060,8 +1060,8 @@
 				     "",
 				     U2H0(read_freq_ctr(&px->fe_sess_per_sec)),
 				     U2H1(px->fe_sps_max), LIM2A2(px->fe_sps_lim, "-"),
-				     U2H3(px->feconn), U2H4(px->feconn_max), U2H5(px->maxconn),
-				     U2H6(px->cum_feconn), U2H7(px->bytes_in), U2H8(px->bytes_out));
+				     U2H3(px->feconn), U2H4(px->counters.feconn_max), U2H5(px->maxconn),
+				     U2H6(px->counters.cum_feconn), U2H7(px->counters.bytes_in), U2H8(px->counters.bytes_out));
 
 				chunk_printf(&msg,
 				     /* denied: req, resp */
@@ -1075,8 +1075,8 @@
 				     /* rest of server: nothing */
 				     "<td align=center colspan=8></td></tr>"
 				     "",
-				     U2H0(px->denied_req), U2H1(px->denied_resp),
-				     U2H2(px->failed_req),
+				     U2H0(px->counters.denied_req), U2H1(px->counters.denied_resp),
+				     U2H2(px->counters.failed_req),
 				     px->state == PR_STRUN ? "OPEN" :
 				     px->state == PR_STIDLE ? "FULL" : "STOP");
 			} else {
@@ -1105,10 +1105,10 @@
 				     ",,,"
 				     "\n",
 				     px->id,
-				     px->feconn, px->feconn_max, px->maxconn, px->cum_feconn,
-				     px->bytes_in, px->bytes_out,
-				     px->denied_req, px->denied_resp,
-				     px->failed_req,
+				     px->feconn, px->counters.feconn_max, px->maxconn, px->counters.cum_feconn,
+				     px->counters.bytes_in, px->counters.bytes_out,
+				     px->counters.denied_req, px->counters.denied_resp,
+				     px->counters.failed_req,
 				     px->state == PR_STRUN ? "OPEN" :
 				     px->state == PR_STIDLE ? "FULL" : "STOP",
 				     relative_pid, px->uuid, STATS_TYPE_FE,
@@ -1190,7 +1190,7 @@
 				     U2H0(sv->nbpend), U2H1(sv->nbpend_max), LIM2A2(sv->maxqueue, "-"),
 				     U2H3(read_freq_ctr(&sv->sess_per_sec)), U2H4(sv->sps_max),
 				     U2H5(sv->cur_sess), U2H6(sv->cur_sess_max), LIM2A7(sv->maxconn, "-"),
-				     U2H8(sv->cum_sess), U2H9(sv->cum_lbconn));
+				     U2H8(sv->counters.cum_sess), U2H9(sv->counters.cum_lbconn));
 
 				chunk_printf(&msg,
 				     /* bytes : in, out */
@@ -1202,10 +1202,10 @@
 				     /* warnings: retries, redispatches */
 				     "<td align=right>%lld</td><td align=right>%lld</td>"
 				     "",
-				     U2H0(sv->bytes_in), U2H1(sv->bytes_out),
-				     U2H2(sv->failed_secu),
-				     U2H3(sv->failed_conns), U2H4(sv->failed_resp),
-				     sv->retries, sv->redispatches);
+				     U2H0(sv->counters.bytes_in), U2H1(sv->counters.bytes_out),
+				     U2H2(sv->counters.failed_secu),
+				     U2H3(sv->counters.failed_conns), U2H4(sv->counters.failed_resp),
+				     sv->counters.retries, sv->counters.redispatches);
 
 				/* status, lest check */
 				chunk_printf(&msg, "<td nowrap>");
@@ -1249,7 +1249,7 @@
 					     "<td align=right>%lld</td><td align=right>%lld</td>"
 					     "<td nowrap align=right>%s</td>"
 					     "",
-					     svs->failed_checks, svs->down_trans,
+					     svs->counters.failed_checks, svs->counters.down_trans,
 					     human_time(srv_downtime(sv), 1));
 				else if (sv != svs)
 					chunk_printf(&msg,
@@ -1293,11 +1293,11 @@
 				     "",
 				     px->id, sv->id,
 				     sv->nbpend, sv->nbpend_max,
-				     sv->cur_sess, sv->cur_sess_max, LIM2A0(sv->maxconn, ""), sv->cum_sess,
-				     sv->bytes_in, sv->bytes_out,
-				     sv->failed_secu,
-				     sv->failed_conns, sv->failed_resp,
-				     sv->retries, sv->redispatches);
+				     sv->cur_sess, sv->cur_sess_max, LIM2A0(sv->maxconn, ""), sv->counters.cum_sess,
+				     sv->counters.bytes_in, sv->counters.bytes_out,
+				     sv->counters.failed_secu,
+				     sv->counters.failed_conns, sv->counters.failed_resp,
+				     sv->counters.retries, sv->counters.redispatches);
 
 				/* status */
 				chunk_printf(&msg,
@@ -1317,7 +1317,7 @@
 				if (sv->state & SRV_CHECKED)
 					chunk_printf(&msg,
 					     "%lld,%lld,%d,%d,",
-					     sv->failed_checks, sv->down_trans,
+					     sv->counters.failed_checks, sv->counters.down_trans,
 					     (int)(now.tv_sec - sv->last_change), srv_downtime(sv));
 				else
 					chunk_printf(&msg,
@@ -1340,7 +1340,7 @@
 				}
 
 				/* sessions: lbtot */
-				chunk_printf(&msg, ",%lld,", sv->cum_lbconn);
+				chunk_printf(&msg, ",%lld,", sv->counters.cum_lbconn);
 
 				/* tracked */
 				if (sv->tracked)
@@ -1410,9 +1410,9 @@
 				     /* bytes : in, out */
 				     "<td align=right>%s</td><td align=right>%s</td>"
 				     "",
-				     U2H2(px->beconn), U2H3(px->beconn_max), U2H4(px->fullconn),
-				     U2H6(px->cum_beconn), U2H7(px->cum_lbconn),
-				     U2H8(px->bytes_in), U2H9(px->bytes_out));
+				     U2H2(px->beconn), U2H3(px->counters.beconn_max), U2H4(px->fullconn),
+				     U2H6(px->counters.cum_beconn), U2H7(px->counters.cum_lbconn),
+				     U2H8(px->counters.bytes_in), U2H9(px->counters.bytes_out));
 
 				chunk_printf(&msg,
 				     /* denied: req, resp */
@@ -1428,9 +1428,9 @@
 				     "<td align=center nowrap>%s %s</td><td align=center>&nbsp;</td><td align=center>%d</td>"
 				     "<td align=center>%d</td><td align=center>%d</td>"
 				     "",
-				     U2H0(px->denied_req), U2H1(px->denied_resp),
-				     U2H2(px->failed_conns), U2H3(px->failed_resp),
-				     px->retries, px->redispatches,
+				     U2H0(px->counters.denied_req), U2H1(px->counters.denied_resp),
+				     U2H2(px->counters.failed_conns), U2H3(px->counters.failed_resp),
+				     px->counters.retries, px->counters.redispatches,
 				     human_time(now.tv_sec - px->last_change, 1),
 				     (px->lbprm.tot_weight > 0 || !px->srv) ? "UP" :
 					     "<font color=\"red\"><b>DOWN</b></font>",
@@ -1478,18 +1478,18 @@
 				     "\n",
 				     px->id,
 				     px->nbpend /* or px->totpend ? */, px->nbpend_max,
-				     px->beconn, px->beconn_max, px->fullconn, px->cum_beconn,
-				     px->bytes_in, px->bytes_out,
-				     px->denied_req, px->denied_resp,
-				     px->failed_conns, px->failed_resp,
-				     px->retries, px->redispatches,
+				     px->beconn, px->counters.beconn_max, px->fullconn, px->counters.cum_beconn,
+				     px->counters.bytes_in, px->counters.bytes_out,
+				     px->counters.denied_req, px->counters.denied_resp,
+				     px->counters.failed_conns, px->counters.failed_resp,
+				     px->counters.retries, px->counters.redispatches,
 				     (px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN",
 				     (px->lbprm.tot_weight * px->lbprm.wmult + px->lbprm.wdiv - 1) / px->lbprm.wdiv,
 				     px->srv_act, px->srv_bck,
 				     px->down_trans, (int)(now.tv_sec - px->last_change),
 				     px->srv?be_downtime(px):0,
 				     relative_pid, px->uuid,
-				     px->cum_lbconn, STATS_TYPE_BE,
+				     px->counters.cum_lbconn, STATS_TYPE_BE,
 				     read_freq_ctr(&px->be_sess_per_sec),
 				     px->be_sps_max);
 			}
diff --git a/src/haproxy.c b/src/haproxy.c
index 37d4eea..83df092 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -281,7 +281,7 @@
 				 "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
 				 p->id, s->id,
 				 (s->state & SRV_RUNNING) ? "UP" : "DOWN",
-				 s->cur_sess, s->nbpend, s->cum_sess);
+				 s->cur_sess, s->nbpend, s->counters.cum_sess);
 			Warning("%s\n", trash);
 			send_log(p, LOG_NOTICE, "%s\n", trash);
 			s = s->next;
@@ -292,19 +292,19 @@
 			snprintf(trash, sizeof(trash),
 				 "SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
 				 p->id,
-				 p->feconn, p->beconn, p->totpend, p->nbpend, p->cum_feconn, p->cum_beconn);
+				 p->feconn, p->beconn, p->totpend, p->nbpend, p->counters.cum_feconn, p->counters.cum_beconn);
 		} else if (p->srv_act == 0) {
 			snprintf(trash, sizeof(trash),
 				 "SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
 				 p->id,
 				 (p->srv_bck) ? "is running on backup servers" : "has no server available",
-				 p->feconn, p->beconn, p->totpend, p->nbpend, p->cum_feconn, p->cum_beconn);
+				 p->feconn, p->beconn, p->totpend, p->nbpend, p->counters.cum_feconn, p->counters.cum_beconn);
 		} else {
 			snprintf(trash, sizeof(trash),
 				 "SIGHUP: Proxy %s has %d active servers and %d backup servers available."
 				 " Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
 				 p->id, p->srv_act, p->srv_bck,
-				 p->feconn, p->beconn, p->totpend, p->nbpend, p->cum_feconn, p->cum_beconn);
+				 p->feconn, p->beconn, p->totpend, p->nbpend, p->counters.cum_feconn, p->counters.cum_beconn);
 		}
 		Warning("%s\n", trash);
 		send_log(p, LOG_NOTICE, "%s\n", trash);
diff --git a/src/proto_http.c b/src/proto_http.c
index 025cd64..8772e6c 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1843,7 +1843,7 @@
 				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
 			msg->msg_state = HTTP_MSG_ERROR;
 			req->analysers = 0;
-			s->fe->failed_req++;
+			s->fe->counters.failed_req++;
 			if (!(s->flags & SN_ERR_MASK))
 				s->flags |= SN_ERR_CLICL;
 			if (!(s->flags & SN_FINST_MASK))
@@ -1860,7 +1860,7 @@
 			stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_408));
 			msg->msg_state = HTTP_MSG_ERROR;
 			req->analysers = 0;
-			s->fe->failed_req++;
+			s->fe->counters.failed_req++;
 			if (!(s->flags & SN_ERR_MASK))
 				s->flags |= SN_ERR_CLITO;
 			if (!(s->flags & SN_FINST_MASK))
@@ -1876,8 +1876,7 @@
 			stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
 			msg->msg_state = HTTP_MSG_ERROR;
 			req->analysers = 0;
-			s->fe->failed_req++;
-
+			s->fe->counters.failed_req++;
 			if (!(s->flags & SN_ERR_MASK))
 				s->flags |= SN_ERR_CLICL;
 			if (!(s->flags & SN_FINST_MASK))
@@ -2006,7 +2005,7 @@
 	txn->req.msg_state = HTTP_MSG_ERROR;
 	txn->status = 400;
 	stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
-	s->fe->failed_req++;
+	s->fe->counters.failed_req++;
 
  return_prx_cond:
 	if (!(s->flags & SN_ERR_MASK))
@@ -2292,7 +2291,7 @@
 	txn->req.msg_state = HTTP_MSG_ERROR;
 	txn->status = 400;
 	stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
-	s->fe->failed_req++;
+	s->fe->counters.failed_req++;
 
  return_prx_cond:
 	if (!(s->flags & SN_ERR_MASK))
@@ -2600,7 +2599,7 @@
 	txn->status = 400;
 	req->analysers = 0;
 	stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
-	s->fe->failed_req++;
+	s->fe->counters.failed_req++;
 
 	if (!(s->flags & SN_ERR_MASK))
 		s->flags |= SN_ERR_PRXCOND;
@@ -2641,8 +2640,8 @@
 
 	req->analysers = 0;
 	req->analyse_exp = TICK_ETERNITY;
+	s->fe->counters.failed_req++;
 
-	s->fe->failed_req++;
 	if (!(s->flags & SN_ERR_MASK))
 		s->flags |= SN_ERR_PRXCOND;
 	if (!(s->flags & SN_FINST_MASK))
@@ -2834,8 +2833,8 @@
 				buffer_shutr_now(rep);
 				buffer_shutw_now(req);
 				if (t->srv)
-					t->srv->failed_resp++;
-				t->be->failed_resp++;
+					t->srv->counters.failed_resp++;
+				t->be->counters.failed_resp++;
 				rep->analysers = 0;
 				txn->status = 502;
 				stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
@@ -2857,8 +2856,8 @@
 				buffer_shutr_now(rep);
 				buffer_shutw_now(req);
 				if (t->srv)
-					t->srv->failed_resp++;
-				t->be->failed_resp++;
+					t->srv->counters.failed_resp++;
+				t->be->counters.failed_resp++;
 				rep->analysers = 0;
 				txn->status = 502;
 				stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
@@ -2875,8 +2874,8 @@
 				buffer_shutr_now(rep);
 				buffer_shutw_now(req);
 				if (t->srv)
-					t->srv->failed_resp++;
-				t->be->failed_resp++;
+					t->srv->counters.failed_resp++;
+				t->be->counters.failed_resp++;
 				rep->analysers = 0;
 				txn->status = 504;
 				stream_int_return(rep->cons, error_message(t, HTTP_ERR_504));
@@ -2892,8 +2891,8 @@
 					http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 				buffer_shutw_now(req);
 				if (t->srv)
-					t->srv->failed_resp++;
-				t->be->failed_resp++;
+					t->srv->counters.failed_resp++;
+				t->be->counters.failed_resp++;
 				rep->analysers = 0;
 				txn->status = 502;
 				stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
@@ -2908,7 +2907,7 @@
 				if (msg->err_pos >= 0)
 					http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 				buffer_shutr_now(rep);
-				t->be->failed_resp++;
+				t->be->counters.failed_resp++;
 				rep->analysers = 0;
 				if (!(t->flags & SN_ERR_MASK))
 					t->flags |= SN_ERR_CLICL;
@@ -2997,8 +2996,8 @@
 				if (apply_filters_to_response(t, rep, rule_set->rsp_exp) < 0) {
 				return_bad_resp:
 					if (t->srv)
-						t->srv->failed_resp++;
-					cur_proxy->failed_resp++;
+						t->srv->counters.failed_resp++;
+					cur_proxy->counters.failed_resp++;
 				return_srv_prx_502:
 					buffer_shutr_now(rep);
 					buffer_shutw_now(req);
@@ -3016,8 +3015,8 @@
 			/* has the response been denied ? */
 			if (txn->flags & TX_SVDENY) {
 				if (t->srv)
-					t->srv->failed_secu++;
-				cur_proxy->denied_resp++;
+					t->srv->counters.failed_secu++;
+				cur_proxy->counters.denied_resp++;
 				goto return_srv_prx_502;
 			}
 
@@ -3157,9 +3156,8 @@
 			 * the 'checkcache' option, and send an alert.
 			 */
 			if (t->srv)
-				t->srv->failed_secu++;
-			t->be->denied_resp++;
-
+				t->srv->counters.failed_secu++;
+			cur_proxy->counters.denied_resp++;
 			Alert("Blocking cacheable cookie in response from instance %s, server %s.\n",
 			      t->be->id, t->srv?t->srv->id:"<dispatch>");
 			send_log(t->be, LOG_ALERT,
@@ -3310,13 +3308,13 @@
 			case ACT_DENY:
 				txn->flags |= TX_CLDENY;
 				last_hdr = 1;
-				t->be->denied_req++;
+				t->be->counters.denied_req++;
 				break;
 
 			case ACT_TARPIT:
 				txn->flags |= TX_CLTARPIT;
 				last_hdr = 1;
-				t->be->denied_req++;
+				t->be->counters.denied_req++;
 				break;
 
 			case ACT_REPLACE:
@@ -3421,13 +3419,13 @@
 
 		case ACT_DENY:
 			txn->flags |= TX_CLDENY;
-			t->be->denied_req++;
+			t->be->counters.denied_req++;
 			done = 1;
 			break;
 
 		case ACT_TARPIT:
 			txn->flags |= TX_CLTARPIT;
-			t->be->denied_req++;
+			t->be->counters.denied_req++;
 			done = 1;
 			break;
 
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index a03c809..df6d034 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -686,7 +686,7 @@
 				buffer_abort(req);
 				buffer_abort(s->rep);
 				req->analysers = 0;
-				s->fe->failed_req++;
+				s->fe->counters.failed_req++;
 				if (!(s->flags & SN_ERR_MASK))
 					s->flags |= SN_ERR_PRXCOND;
 				if (!(s->flags & SN_FINST_MASK))
diff --git a/src/proxy.c b/src/proxy.c
index 8683e74..c7b1f4d 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -645,8 +645,8 @@
 		return 1;
 	s->be = be;
 	be->beconn++;
-	if (be->beconn > be->beconn_max)
-		be->beconn_max = be->beconn;
+	if (be->beconn > be->counters.beconn_max)
+		be->counters.beconn_max = be->beconn;
 	proxy_inc_be_ctr(be);
 
 	/* assign new parameters to the session from the new backend */
diff --git a/src/session.c b/src/session.c
index e359eb1..9d46fe6 100644
--- a/src/session.c
+++ b/src/session.c
@@ -139,13 +139,13 @@
 		bytes = s->req->total - s->logs.bytes_in;
 		s->logs.bytes_in = s->req->total;
 		if (bytes) {
-			s->fe->bytes_in          += bytes;
+			s->fe->counters.bytes_in			+= bytes;
 
 			if (s->be != s->fe)
-				s->be->bytes_in  += bytes;
+				s->be->counters.bytes_in		+= bytes;
 
 			if (s->srv)
-				s->srv->bytes_in += bytes;
+				s->srv->counters.bytes_in		+= bytes;
 		}
 	}
 
@@ -153,13 +153,13 @@
 		bytes = s->rep->total - s->logs.bytes_out;
 		s->logs.bytes_out = s->rep->total;
 		if (bytes) {
-			s->fe->bytes_out          += bytes;
+			s->fe->counters.bytes_out			+= bytes;
 
 			if (s->be != s->fe)
-				s->be->bytes_out  += bytes;
+				s->be->counters.bytes_out		+= bytes;
 
 			if (s->srv)
-				s->srv->bytes_out += bytes;
+				s->srv->counters.bytes_out		+= bytes;
 		}
 	}
 }
@@ -255,8 +255,8 @@
 		}
 
 		if (s->srv)
-			s->srv->failed_conns++;
-		s->be->failed_conns++;
+			s->srv->counters.failed_conns++;
+		s->be->counters.failed_conns++;
 		if (may_dequeue_tasks(s->srv, s->be))
 			process_srv_queue(s->srv);
 
@@ -286,8 +286,8 @@
 		si->state = SI_ST_REQ;
 	} else {
 		if (s->srv)
-			s->srv->retries++;
-		s->be->retries++;
+			s->srv->counters.retries++;
+		s->be->counters.retries++;
 		si->state = SI_ST_ASS;
 	}
 
@@ -381,8 +381,8 @@
 			if (s->srv)
 				srv_inc_sess_ctr(s->srv);
 			if (s->srv)
-				s->srv->failed_conns++;
-			s->be->failed_conns++;
+				s->srv->counters.failed_conns++;
+			s->be->counters.failed_conns++;
 
 			/* release other sessions waiting for this server */
 			if (may_dequeue_tasks(s->srv, s->be))
@@ -436,8 +436,8 @@
 			si->exp = TICK_ETERNITY;
 			s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
 			if (s->srv)
-				s->srv->failed_conns++;
-			s->be->failed_conns++;
+				s->srv->counters.failed_conns++;
+			s->be->counters.failed_conns++;
 			si->shutr(si);
 			si->shutw(si);
 			si->ob->flags |= BF_WRITE_TIMEOUT;
@@ -698,9 +698,9 @@
 			s->si[1].shutr(&s->si[1]);
 			s->si[1].shutw(&s->si[1]);
 			stream_int_report_error(&s->si[1]);
-			s->be->failed_resp++;
+			s->be->counters.failed_resp++;
 			if (s->srv)
-				s->srv->failed_resp++;
+				s->srv->counters.failed_resp++;
 			if (!(s->req->analysers) && !(s->rep->analysers)) {
 				if (!(s->flags & SN_ERR_MASK))
 					s->flags |= SN_ERR_SRVCL;
@@ -1309,7 +1309,7 @@
 {
 	if (!(s->flags & SN_FINST_MASK)) {
 		if (s->si[1].state < SI_ST_REQ) {
-			s->fe->failed_req++;
+			s->fe->counters.failed_req++;
 			s->flags |= SN_FINST_R;
 		}
 		else if (s->si[1].state == SI_ST_QUE)