[MINOR] acl: add 2 new verbs: fe_sess_rate and be_sess_rate

These new ACLs match frontend session rate and backend session rate.
Examples are provided in the doc to explain how to use that in order
to limit abuse of service.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 84465e8..24bf1bc 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -4070,6 +4070,44 @@
   dynamic connections. Also, if any of the server maxconn, or maxqueue is 0, then
   this acl clearly does not make sense - in which case the value returned will be -1.
 
+fe_sess_rate <integer>
+fe_sess_rate(frontend) <integer>
+  Returns true when the session creation rate on the current or the named
+  frontend matches the specified values or ranges, expressed in new sessions
+  per second. This is used to limit the connection rate to acceptable ranges in
+  order to prevent abuse of service at the earliest moment. This can be
+  combined with layer 4 ACLs in order to force the clients to wait a bit for
+  the rate to go down below the limit.
+
+  Example :
+        # This frontend limits incoming mails to 10/s with a max of 100
+        # concurrent connections. We accept any connection below 10/s, and
+        # force excess clients to wait for 100 ms. Since clients are limited to
+        # 100 max, there cannot be more than 10 incoming mails per second.
+        frontend mail
+            bind :25
+            mode tcp
+            maxconn 100
+            acl too_fast fe_sess_rate ge 10
+            tcp-request inspect-delay 100ms
+            tcp-request content accept if ! too_fast
+            tcp-request content accept if WAIT_END
+  
+be_sess_rate <integer>
+be_sess_rate(backend) <integer>
+  Returns true when the sessions creation rate on the backend matches the
+  specified values or ranges, in number of new sessions per second. This is
+  used to switch to an alternate backend when an expensive or fragile one
+  reaches too high a session rate, or to limite abuse of service (eg. prevent
+  sucking of an online dictionary).
+
+  Example :
+        # Redirect to an error page if the dictionary is requested too often
+        backend dynamic
+            mode http
+            acl being_scanned be_sess_rate gt 100
+            redirect location /denied.html if being_scanned
+
 
 2.3.5.2) Matching contents at Layer 4
 -------------------------------------
diff --git a/src/backend.c b/src/backend.c
index 73fb112..d386805 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -2096,11 +2096,51 @@
 	return 1;
 }
 
+/* set test->i to the number of connections per second reaching the frontend */
+static int
+acl_fetch_fe_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
+                       struct acl_expr *expr, struct acl_test *test)
+{
+	test->flags = ACL_TEST_F_VOL_TEST;
+	if (expr->arg_len) {
+		/* another proxy was designated, we must look for it */
+		for (px = proxy; px; px = px->next)
+			if ((px->cap & PR_CAP_FE) && !strcmp(px->id, expr->arg.str))
+				break;
+	}
+	if (!px)
+		return 0;
+
+	test->i = read_freq_ctr(&px->fe_sess_per_sec);
+	return 1;
+}
+
+/* set test->i to the number of connections per second reaching the backend */
+static int
+acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
+                       struct acl_expr *expr, struct acl_test *test)
+{
+	test->flags = ACL_TEST_F_VOL_TEST;
+	if (expr->arg_len) {
+		/* another proxy was designated, we must look for it */
+		for (px = proxy; px; px = px->next)
+			if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str))
+				break;
+	}
+	if (!px)
+		return 0;
+
+	test->i = read_freq_ctr(&px->be_sess_per_sec);
+	return 1;
+}
+
 
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct acl_kw_list acl_kws = {{ },{
 	{ "nbsrv",    acl_parse_int,   acl_fetch_nbsrv,     acl_match_int, ACL_USE_NOTHING },
 	{ "connslots", acl_parse_int,   acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING },
+	{ "fe_sess_rate", acl_parse_int, acl_fetch_fe_sess_rate, acl_match_int, ACL_USE_NOTHING },
+	{ "be_sess_rate", acl_parse_int, acl_fetch_be_sess_rate, acl_match_int, ACL_USE_NOTHING },
 	{ NULL, NULL, NULL, NULL },
 }};