[MINOR] acl: add fe_conn, be_conn, queue, avg_queue
These ACLs are used to check the number of active connections on the
frontend, backend or in a backend's queue. The avg_queue returns the
average number of queued connections per server, and for this, divides
the total number of queued connections by the number of alive servers.
The dst_conn ACL has been slightly changed to more reflect its name and
original usage, which is to return the number of connections on the
destination address/port (the socket) and not the whole frontend.
diff --git a/src/backend.c b/src/backend.c
index 77c5a92..f4e6110 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1188,7 +1188,7 @@
test->i = 0;
iterator = px->srv;
while (iterator) {
- if ((iterator->state & 1) == 0) {
+ if ((iterator->state & SRV_RUNNING) == 0) {
iterator = iterator->next;
continue;
}
@@ -1243,6 +1243,99 @@
return 1;
}
+/* set test->i to the number of concurrent connections on the frontend */
+static int
+acl_fetch_fe_conn(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 = px->feconn;
+ return 1;
+}
+
+/* set test->i to the number of concurrent connections on the backend */
+static int
+acl_fetch_be_conn(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 = px->beconn;
+ return 1;
+}
+
+/* set test->i to the total number of queued connections on the backend */
+static int
+acl_fetch_queue_size(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 = px->totpend;
+ return 1;
+}
+
+/* set test->i to the total number of queued connections on the backend divided
+ * by the number of running servers and rounded up. If there is no running
+ * server, we return twice the total, just as if we had half a running server.
+ * This is more or less correct anyway, since we expect the last server to come
+ * back soon.
+ */
+static int
+acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
+ struct acl_expr *expr, struct acl_test *test)
+{
+ int nbsrv;
+
+ 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;
+
+ if (px->srv_act)
+ nbsrv = px->srv_act;
+ else if (px->lbprm.fbck)
+ nbsrv = 1;
+ else
+ nbsrv = px->srv_bck;
+
+ if (nbsrv > 0)
+ test->i = (px->totpend + nbsrv - 1) / nbsrv;
+ else
+ test->i = px->totpend * 2;
+
+ return 1;
+}
/* Note: must not be declared <const> as its list will be overwritten */
static struct acl_kw_list acl_kws = {{ },{
@@ -1250,6 +1343,10 @@
{ "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 },
+ { "fe_conn", acl_parse_int, acl_fetch_fe_conn, acl_match_int, ACL_USE_NOTHING },
+ { "be_conn", acl_parse_int, acl_fetch_be_conn, acl_match_int, ACL_USE_NOTHING },
+ { "queue", acl_parse_int, acl_fetch_queue_size, acl_match_int, ACL_USE_NOTHING },
+ { "avg_queue", acl_parse_int, acl_fetch_avg_queue_size, acl_match_int, ACL_USE_NOTHING },
{ NULL, NULL, NULL, NULL },
}};
diff --git a/src/client.c b/src/client.c
index 3bd31cf..b9e304a 100644
--- a/src/client.c
+++ b/src/client.c
@@ -593,12 +593,12 @@
}
-/* set test->i to the number of connexions to the proxy */
+/* set test->i to the number of connexions to the same listening socket */
static int
acl_fetch_dconn(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
- test->i = px->feconn;
+ test->i = l4->listener->nbconn;
return 1;
}