[MEDIUM] session-counters: correctly unbind the counters tracked by the backend

In case of HTTP keepalive processing, we want to release the counters tracked
by the backend. Till now only the second set of counters was released, while
it could have been assigned by the frontend, or the backend could also have
assigned the first set. Now we reuse to unused bits of the session flags to
mark which stick counters were assigned by the backend and to release them as
appropriate.
This commit is contained in:
Willy Tarreau 2010-08-06 20:11:05 +02:00
parent 56123282ef
commit 0a4838cd31
3 changed files with 33 additions and 15 deletions

View File

@ -82,15 +82,27 @@ static inline void session_stop_backend_counters(struct session *s)
{
void *ptr;
if (!s->stkctr2_entry)
if (!(s->flags & (SN_BE_TRACK_SC1|SN_BE_TRACK_SC2)))
return;
ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_CONN_CUR);
if (ptr)
stktable_data_cast(ptr, conn_cur)--;
s->stkctr2_entry->ref_cnt--;
stksess_kill_if_expired(s->stkctr2_table, s->stkctr2_entry);
s->stkctr2_entry = NULL;
if ((s->flags & SN_BE_TRACK_SC1) && s->stkctr1_entry) {
ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_CONN_CUR);
if (ptr)
stktable_data_cast(ptr, conn_cur)--;
s->stkctr1_entry->ref_cnt--;
stksess_kill_if_expired(s->stkctr1_table, s->stkctr1_entry);
s->stkctr1_entry = NULL;
}
if ((s->flags & SN_BE_TRACK_SC2) && s->stkctr2_entry) {
ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_CONN_CUR);
if (ptr)
stktable_data_cast(ptr, conn_cur)--;
s->stkctr2_entry->ref_cnt--;
stksess_kill_if_expired(s->stkctr2_table, s->stkctr2_entry);
s->stkctr2_entry = NULL;
}
s->flags &= ~(SN_BE_TRACK_SC1|SN_BE_TRACK_SC2);
}
/* Increase total and concurrent connection count for stick entry <ts> of table

View File

@ -67,7 +67,7 @@
#define SN_ERR_INTERNAL 0x00007000 /* the proxy encountered an internal error */
#define SN_ERR_MASK 0x00007000 /* mask to get only session error flags */
#define SN_ERR_SHIFT 12 /* bit shift */
/* unused: 0x00008000 */
#define SN_BE_TRACK_SC1 0x00008000 /* backend tracks stick-counter 1 */
/* session state at termination, bits values 0x10000 to 0x70000 (0-7 shift 16) */
#define SN_FINST_R 0x00010000 /* session ended during client request */
@ -79,14 +79,10 @@
#define SN_FINST_T 0x00070000 /* session ended tarpitted */
#define SN_FINST_MASK 0x00070000 /* mask to get only final session state flags */
#define SN_FINST_SHIFT 16 /* bit shift */
/* unused: 0x00080000 */
#define SN_BE_TRACK_SC2 0x00080000 /* backend tracks stick-counter 2 */
#define SN_IGNORE_PRST 0x00100000 /* ignore persistence */
/* WARNING: if new fields are added, they must be initialized in event_accept()
* and freed in session_free() !
*/
/* Termination sequence tracing.
*
* These values have to be set into the field term_trace of a session when
@ -143,6 +139,10 @@ enum {
};
/* WARNING: if new fields are added, they must be initialized in event_accept()
* and freed in session_free() !
*/
/*
* Note: some session flags have dependencies :
* - SN_DIRECT cannot exist without SN_ASSIGNED, because a server is

View File

@ -695,8 +695,11 @@ int tcp_inspect_request(struct session *s, struct buffer *req, int an_bit)
*/
t = rule->act_prm.trk_ctr.table.t;
ts = stktable_get_entry(t, tcpv4_src_to_stktable_key(s));
if (ts)
if (ts) {
session_track_stkctr1(s, t, ts);
if (s->fe != s->be)
s->flags |= SN_BE_TRACK_SC1;
}
}
}
else if (rule->action == TCP_ACT_TRK_SC2) {
@ -708,8 +711,11 @@ int tcp_inspect_request(struct session *s, struct buffer *req, int an_bit)
*/
t = rule->act_prm.trk_ctr.table.t;
ts = stktable_get_entry(t, tcpv4_src_to_stktable_key(s));
if (ts)
if (ts) {
session_track_stkctr2(s, t, ts);
if (s->fe != s->be)
s->flags |= SN_BE_TRACK_SC2;
}
}
}
else {