[MINOR] session-counters: add the ability to clear the counters

Sometimes it can be useful to reset a counter : one condition increments
it and another one resets it. It can be used to better detect abuses.
This commit is contained in:
Willy Tarreau 2011-08-13 01:45:16 +02:00
parent 927cdddf9c
commit f73cd1198f
2 changed files with 101 additions and 0 deletions

View File

@ -7231,6 +7231,23 @@ sc2_bytes_out_rate
counters, measured in amount of bytes over the period configured in the
table. See also src_bytes_out_rate.
sc1_clr_gpc0
sc2_clr_gpc0
Clears the first General Purpose Counter associated to the currently tracked
counters, and returns its previous value. Before the first invocation, the
stored value is zero, so first invocation will always return zero. The test
can also be used alone and always returns true. This is typically used as a
second ACL in an expression in order to mark a connection when a first ACL
was verified :
# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse sc1_http_req_rate gt 10
acl kill sc1_inc_gpc0 gt 5
acl save sc1_clr_gpc0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill
sc1_conn_cnt
sc2_conn_cnt
Returns the cumulated number of incoming connections from currently tracked
@ -7346,6 +7363,23 @@ src_bytes_out_rate(<table>) <integer>
amount of bytes over the period configured in the table. If the address is
not found, zero is returned. See also sc1/sc2_bytes_out_rate.
src_clr_gpc0 <integer>
src_clr_gpc0(<table>) <integer>
Clears the first General Purpose Counter associated to the connection's
source IPv4 address in the current proxy's stick-table or in the designated
stick-table, and returns its previous value. If the address is not found, an
entry is created and 0 is returned. The test can also be used alone and
always returns true. This is typically used as a second ACL in an expression
in order to mark a connection when a first ACL was verified :
# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse src_http_req_rate gt 10
acl kill src_inc_gpc0 gt 5
acl save src_clr_gpc0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill
src_conn_cnt <integer>
src_conn_cnt(<table>) <integer>
Returns the cumulated number of connections initiated from the current

View File

@ -2342,6 +2342,70 @@ acl_fetch_src_inc_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
return acl_fetch_inc_gpc0(&px->table, test, stktable_update_key(&px->table, key));
}
/* Clear the General Purpose Counter 0 value in the stksess entry <ts> and
* return its previous value into test->i.
*/
static int
acl_fetch_clr_gpc0(struct stktable *table, struct acl_test *test, struct stksess *ts)
{
test->flags = ACL_TEST_F_VOL_TEST;
test->i = 0;
if (ts != NULL) {
void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0);
if (!ptr)
return 0; /* parameter not stored */
test->i = stktable_data_cast(ptr, gpc0);
stktable_data_cast(ptr, gpc0) = 0;
}
return 1;
}
/* Clear the General Purpose Counter 0 value from the session's tracked
* frontend counters and return its previous value into test->i.
*/
static int
acl_fetch_sc1_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
if (!l4->stkctr1_entry)
return 0;
return acl_fetch_clr_gpc0(l4->stkctr1_table, test, l4->stkctr1_entry);
}
/* Clear the General Purpose Counter 0 value from the session's tracked
* backend counters and return its previous value into test->i.
*/
static int
acl_fetch_sc2_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
if (!l4->stkctr2_entry)
return 0;
return acl_fetch_clr_gpc0(l4->stkctr2_table, test, l4->stkctr2_entry);
}
/* Clear the General Purpose Counter 0 value from the session's source address
* in the table pointed to by expr, and return its previous value into test->i.
*/
static int
acl_fetch_src_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
struct stktable_key *key;
key = tcp_src_to_stktable_key(l4);
if (!key)
return 0;
if (expr->arg_len)
px = find_stktable(expr->arg.str);
if (!px)
return 0; /* table not found */
return acl_fetch_clr_gpc0(&px->table, test, stktable_update_key(&px->table, key));
}
/* set test->i to the cumulated number of connections in the stksess entry <ts> */
static int
acl_fetch_conn_cnt(struct stktable *table, struct acl_test *test, struct stksess *ts)
@ -3228,6 +3292,9 @@ static struct acl_kw_list acl_kws = {{ },{
{ "sc1_inc_gpc0", acl_parse_int, acl_fetch_sc1_inc_gpc0, acl_match_int, ACL_USE_NOTHING },
{ "sc2_inc_gpc0", acl_parse_int, acl_fetch_sc2_inc_gpc0, acl_match_int, ACL_USE_NOTHING },
{ "src_inc_gpc0", acl_parse_int, acl_fetch_src_inc_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE },
{ "sc1_clr_gpc0", acl_parse_int, acl_fetch_sc1_clr_gpc0, acl_match_int, ACL_USE_NOTHING },
{ "sc2_clr_gpc0", acl_parse_int, acl_fetch_sc2_clr_gpc0, acl_match_int, ACL_USE_NOTHING },
{ "src_clr_gpc0", acl_parse_int, acl_fetch_src_clr_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE },
{ "sc1_conn_cnt", acl_parse_int, acl_fetch_sc1_conn_cnt, acl_match_int, ACL_USE_NOTHING },
{ "sc2_conn_cnt", acl_parse_int, acl_fetch_sc2_conn_cnt, acl_match_int, ACL_USE_NOTHING },
{ "src_conn_cnt", acl_parse_int, acl_fetch_src_conn_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE },