MINOR: backend: rename sample fetch functions and declare the sample keywords

The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

  avg_queue, be_conn, be_id, be_sess_rate, connslots, nbsrv,
  queue, srv_conn, srv_id, srv_is_up, srv_sess_rate

The fetch functions have been renamed "smp_fetch_*".
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 2f6b869..d01622b 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -9548,6 +9548,25 @@
   always_true
                Always returns the boolean "true" value.
 
+  avg_queue([<backend>])
+               Returns the total number of queued connections of the designated
+               backend divided by the number of active servers. The current
+               backend is used if no backend is specified. This is very similar
+               to "queue" except that the size of the farm is considered, in
+               order to give a more accurate measurement of the time it may
+               take for a new connection to be processed. The main usage is
+               with ACL to return a sorry page to new users when it becomes
+               certain they will get a degraded service, or to pass to the
+               backend servers in a header so that they decide to work in
+               degraded mode or to disable some functions to speed up the
+               processing a bit. Note that in the event there would not be
+               any active server anymore, we would consider twice the number
+               of queued connections as the measured value. This is a fair
+               estimate, as we expect one server to get back soon anyway, but
+               we still prefer to send new traffic to another backend if in
+               better shape. See also the "queue", "be_conn", and
+               "be_sess_rate" sample fetches.
+
   base         This returns the concatenation of the first Host header and the
                path part of the request, which starts at the first slash and
                ends before the question mark. It can be useful in virtual
@@ -9567,6 +9586,32 @@
                size of 8 or 20 bytes depending on the source address family.
                This can be used to track per-IP, per-URL counters.
 
+  be_conn([<backend>])
+               Returns the number of currently established connections on the
+               the backend, possibly including the connection being evaluated.
+               If no backend name is specified, the current one is used. But it
+               is also possible to check another backend. It can be used to use
+               a specific farm when the nominal one is full.  See also the
+               "fe_conn", "queue" and "be_sess_rate" criteria.
+
+  be_id        Returns an integer containing the current backend's id.
+
+  be_sess_rate([<backend>])
+               Returns an integer value corresponding to the sessions creation
+               rate on the backend, in number of new sessions per second. This
+               is used with ACLs to switch to an alternate backend when an
+               expensive or fragile one reaches too high a session rate, or to
+               limit abuse of service (eg. prevent sucking of an online
+               dictionary). It can also be useful to add this element to logs
+               using a log-format directive.
+
+  connslots([<backend>])
+               Returns an integer value corresponding to the number of
+               connection slots still available in the backend, by totalizing
+               the maximum amount of connections on all servers and the maximum
+               queue size. This is only used with ACLs. See the ACL "connslots"
+               keyword description for more information on possible caveats.
+
   cookie(<name>)
                This extracts the last occurrence of the cookie name <name> on a
                "Cookie" header line from the request, or a "Set-Cookie" header
@@ -9600,6 +9645,12 @@
                last one. A typical use is with the X-Forwarded-For header once
                converted to IP, associated with an IP stick-table.
 
+  nbsrv([<backend>])
+               Returns an integer value corresponding to the number of usable
+               servers of either the current backend or the named backend. This
+               is mostly used with ACLs but can also be useful when added to
+               logs.
+
   path         This extracts the request's URL path (without the host part). A
                typical use is with prefetch-capable caches, and with portals
                which need to aggregate multiple information from databases and
@@ -9622,6 +9673,13 @@
                <lengthoffset> + <lengthsize> else it is absolute.
                Ex: see SSL session id  example in "stick table" chapter.
 
+  queue([<backend>])
+               Returns the total number of queued connections of the designated
+               backend, including all the connections in server queues. If no
+               backend name is specified, the current one is used, but it is
+               also possible to check another one. This is useful with ACLs
+               or to pass statistics to backend servers.
+
   rdp_cookie(<name>)
                This extracts the value of the rdp cookie <name> as a string
                and uses this value to match. This enables implementation of
@@ -9718,6 +9776,27 @@
                that this function will be useful but it's available at no cost.
                It is of type integer and only works with such tables.
 
+  srv_conn(<backend>/<server>)
+               Returns an integer value corresponding to the number of
+               currently established connections on this server, possibly
+               including the connection being evaluated. It is only used with
+               ACLs.
+
+  srv_id       Returns an integer containing the server's id when processing
+               the response. While it's almost only used with ACLs, it may be
+               used for logging or debugging.
+
+  srv_is_up([<backend>/]<server>)
+               Returns a the boolean TRUE value when the designated server is
+               UP, and false when it is either DOWN or in maintenance mode. If
+               <backend> is omitted, then the server is looked up in the
+               current backend. It is almost only used with ACLs.
+
+  srv_sess_rate(<backend>/<server>)
+               Returns an integer corresponding to the sessions creation rate
+               on the server, in number of new sessions per second. This is
+               used with ACLs but may make sense with logs too.
+
   ssl_c_ca_err Returns the ID of the first error detected during verify of the
                client certificate at depth > 0, or 0 if no error was detected.
 
diff --git a/src/backend.c b/src/backend.c
index dcec6b2..4c2d9e8 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1,7 +1,7 @@
 /*
  * Backend variables and functions.
  *
- * Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
+ * Copyright 2000-2013 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
@@ -1370,7 +1370,7 @@
 
 
 /************************************************************************/
-/*             All supported keywords must be declared here.            */
+/*      All supported sample and ACL keywords must be declared here.    */
 /************************************************************************/
 
 /* set temp integer to the number of enabled servers on the proxy.
@@ -1378,7 +1378,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                 const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TEST;
@@ -1401,7 +1401,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                     const struct arg *args, struct sample *smp)
 {
 	struct server *srv = args->data.srv;
@@ -1421,7 +1421,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_connslots(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                     const struct arg *args, struct sample *smp)
 {
 	struct server *iterator;
@@ -1449,7 +1449,7 @@
 
 /* set temp integer to the id of the backend */
 static int
-acl_fetch_be_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_be_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                 const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TXN;
@@ -1460,7 +1460,7 @@
 
 /* set temp integer to the id of the server */
 static int
-acl_fetch_srv_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_srv_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                  const struct arg *args, struct sample *smp)
 {
 	if (!objt_server(l4->target))
@@ -1477,7 +1477,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TEST;
@@ -1491,7 +1491,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                   const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TEST;
@@ -1505,7 +1505,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                      const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TEST;
@@ -1523,7 +1523,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                          const struct arg *args, struct sample *smp)
 {
 	int nbsrv;
@@ -1552,7 +1552,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_srv_conn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_srv_conn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                    const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TEST;
@@ -1566,7 +1566,7 @@
  * undefined behaviour.
  */
 static int
-acl_fetch_srv_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+smp_fetch_srv_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                         const struct arg *args, struct sample *smp)
 {
 	smp->flags = SMP_F_VOL_TEST;
@@ -1575,28 +1575,49 @@
 	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 sample_fetch_kw_list smp_kws = {{ },{
+	{ "avg_queue",     smp_fetch_avg_queue_size, ARG1(1,BE),  NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "be_conn",       smp_fetch_be_conn,        ARG1(1,BE),  NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "be_id",         smp_fetch_be_id,          0,           NULL, SMP_T_UINT, SMP_USE_BKEND, },
+	{ "be_sess_rate",  smp_fetch_be_sess_rate,   ARG1(1,BE),  NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "connslots",     smp_fetch_connslots,      ARG1(1,BE),  NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "nbsrv",         smp_fetch_nbsrv,          ARG1(1,BE),  NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "queue",         smp_fetch_queue_size,     ARG1(1,BE),  NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "srv_conn",      smp_fetch_srv_conn,       ARG1(1,SRV), NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ "srv_id",        smp_fetch_srv_id,         0,           NULL, SMP_T_UINT, SMP_USE_SERVR, },
+	{ "srv_is_up",     smp_fetch_srv_is_up,      ARG1(1,SRV), NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+	{ "srv_sess_rate", smp_fetch_srv_sess_rate,  ARG1(1,SRV), NULL, SMP_T_UINT, SMP_USE_INTRN, },
+	{ /* END */ },
+}};
+
+
 /* 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 = {{ },{
-	{ "avg_queue",    acl_parse_int,     acl_fetch_avg_queue_size, acl_match_int,     ACL_USE_NOTHING, ARG1(1,BE) },
-	{ "be_conn",      acl_parse_int,     acl_fetch_be_conn,        acl_match_int,     ACL_USE_NOTHING, ARG1(1,BE) },
-	{ "be_id",        acl_parse_int,     acl_fetch_be_id,          acl_match_int,     ACL_USE_NOTHING, 0 },
-	{ "be_sess_rate", acl_parse_int,     acl_fetch_be_sess_rate,   acl_match_int,     ACL_USE_NOTHING, ARG1(1,BE) },
-	{ "connslots",    acl_parse_int,     acl_fetch_connslots,      acl_match_int,     ACL_USE_NOTHING, ARG1(1,BE) },
-	{ "nbsrv",        acl_parse_int,     acl_fetch_nbsrv,          acl_match_int,     ACL_USE_NOTHING, ARG1(1,BE) },
-	{ "queue",        acl_parse_int,     acl_fetch_queue_size,     acl_match_int,     ACL_USE_NOTHING, ARG1(1,BE) },
-	{ "srv_conn",     acl_parse_int,     acl_fetch_srv_conn,       acl_match_int,     ACL_USE_NOTHING, ARG1(1,SRV) },
-	{ "srv_id",       acl_parse_int,     acl_fetch_srv_id,         acl_match_int,     ACL_USE_RTR_INTERNAL, 0 },
-	{ "srv_is_up",    acl_parse_nothing, acl_fetch_srv_is_up,      acl_match_nothing, ACL_USE_NOTHING, ARG1(1,SRV) },
-	{ "srv_sess_rate", acl_parse_int,    acl_fetch_srv_sess_rate,  acl_match_int,     ACL_USE_NOTHING, ARG1(1,SRV) },
-	{ NULL, NULL, NULL, NULL },
+	{ "avg_queue",     acl_parse_int,     smp_fetch_avg_queue_size, acl_match_int,     ACL_USE_NOTHING,      ARG1(1,BE)  },
+	{ "be_conn",       acl_parse_int,     smp_fetch_be_conn,        acl_match_int,     ACL_USE_NOTHING,      ARG1(1,BE)  },
+	{ "be_id",         acl_parse_int,     smp_fetch_be_id,          acl_match_int,     ACL_USE_NOTHING,      0           },
+	{ "be_sess_rate",  acl_parse_int,     smp_fetch_be_sess_rate,   acl_match_int,     ACL_USE_NOTHING,      ARG1(1,BE)  },
+	{ "connslots",     acl_parse_int,     smp_fetch_connslots,      acl_match_int,     ACL_USE_NOTHING,      ARG1(1,BE)  },
+	{ "nbsrv",         acl_parse_int,     smp_fetch_nbsrv,          acl_match_int,     ACL_USE_NOTHING,      ARG1(1,BE)  },
+	{ "queue",         acl_parse_int,     smp_fetch_queue_size,     acl_match_int,     ACL_USE_NOTHING,      ARG1(1,BE)  },
+	{ "srv_conn",      acl_parse_int,     smp_fetch_srv_conn,       acl_match_int,     ACL_USE_NOTHING,      ARG1(1,SRV) },
+	{ "srv_id",        acl_parse_int,     smp_fetch_srv_id,         acl_match_int,     ACL_USE_RTR_INTERNAL, 0           },
+	{ "srv_is_up",     acl_parse_nothing, smp_fetch_srv_is_up,      acl_match_nothing, ACL_USE_NOTHING,      ARG1(1,SRV) },
+	{ "srv_sess_rate", acl_parse_int,     smp_fetch_srv_sess_rate,  acl_match_int,     ACL_USE_NOTHING,      ARG1(1,SRV) },
+	{ /* END */ },
 }};
 
 
 __attribute__((constructor))
 static void __backend_init(void)
 {
+	sample_register_fetches(&smp_kws);
 	acl_register_keywords(&acl_kws);
 }