src_port <integer>
Applies to the client's TCP source port. This has a very limited usage.
+srv_is_up(<server>)
+srv_is_up(<backend>/<server>)
+ Returns true 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. The function takes no arguments since it
+ is used as a boolean. It is mainly used to take action based on an external
+ status reported via a health check (eg: a geographical site's availability).
+ Another possible use which is more of a hack consists in using dummy servers
+ as boolean variables that can be enabled or disabled from the CLI, so that
+ rules depending on those ACLs can be tweaked in realtime.
+
7.5.2. Matching contents at Layer 4
-----------------------------------
* include/types/acl.h
* This file provides structures and types for ACLs.
*
- * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
+ * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <types/auth.h>
#include <types/proxy.h>
+#include <types/server.h>
#include <types/session.h>
#include <ebmbtree.h>
union { /* optional argument of the subject (eg: header or cookie name) */
char *str;
struct userlist *ul;
+ struct server *srv;
} arg;
int arg_len; /* optional argument length */
struct list patterns; /* list of acl_patterns */
#include <proto/acl.h>
#include <proto/auth.h>
#include <proto/log.h>
+#include <proto/proxy.h>
#include <ebsttree.h>
list_for_each_entry(acl, &p->acl, list) {
list_for_each_entry(expr, &acl->expr, list) {
+ if (strcmp(expr->kw->kw, "srv_is_up") == 0) {
+ struct proxy *px;
+ struct server *srv;
+ char *pname, *sname;
+
+ if (!expr->arg.str || !*expr->arg.str) {
+ Alert("proxy %s: acl %s %s(): missing server name.\n",
+ p->id, acl->name, expr->kw->kw);
+ cfgerr++;
+ continue;
+ }
+
+ pname = expr->arg.str;
+ sname = strrchr(pname, '/');
+
+ if (sname)
+ *sname++ = '\0';
+ else {
+ sname = pname;
+ pname = NULL;
+ }
+
+ px = p;
+ if (pname) {
+ px = findproxy(pname, PR_CAP_BE);
+ if (!px) {
+ Alert("proxy %s: acl %s %s(): unable to find proxy '%s'.\n",
+ p->id, acl->name, expr->kw->kw, pname);
+ cfgerr++;
+ continue;
+ }
+ }
+
+ srv = findserver(px, sname);
+ if (!srv) {
+ Alert("proxy %s: acl %s %s(): unable to find server '%s'.\n",
+ p->id, acl->name, expr->kw->kw, sname);
+ cfgerr++;
+ continue;
+ }
+
+ free(expr->arg.str);
+ expr->arg_len = 0;
+ expr->arg.srv = srv;
+ continue;
+ }
+
if (strstr(expr->kw->kw, "http_auth") == expr->kw->kw) {
if (!expr->arg.str || !*expr->arg.str) {
return 1;
}
+/* report in test->flags a success or failure depending on the designated
+ * server's state. There is no match function involved since there's no pattern.
+ */
+static int
+acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, int dir,
+ struct acl_expr *expr, struct acl_test *test)
+{
+ struct server *srv = expr->arg.srv;
+
+ test->flags = ACL_TEST_F_VOL_TEST;
+ if (!(srv->state & SRV_MAINTAIN) &&
+ (!(srv->state & SRV_CHECKED) || (srv->state & SRV_RUNNING)))
+ test->flags |= ACL_TEST_F_SET_RES_PASS;
+ else
+ test->flags |= ACL_TEST_F_SET_RES_FAIL;
+ return 1;
+}
+
/* set test->i to the number of enabled servers on the proxy */
static int
acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
{ "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 },
+ { "srv_is_up", acl_parse_nothing, acl_fetch_srv_is_up, acl_match_nothing, ACL_USE_NOTHING },
{ NULL, NULL, NULL, NULL },
}};