From 0a4838cd31cd3dbb1078f78061a532ad0e519f3b Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 6 Aug 2010 20:11:05 +0200 Subject: [PATCH] [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. --- include/proto/session.h | 26 +++++++++++++++++++------- include/types/session.h | 12 ++++++------ src/proto_tcp.c | 10 ++++++++-- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/proto/session.h b/include/proto/session.h index f33f924d0f..15f3fe744a 100644 --- a/include/proto/session.h +++ b/include/proto/session.h @@ -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 of table diff --git a/include/types/session.h b/include/types/session.h index 79a8373319..d1e54acff4 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -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 diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 5882791817..301666f3c6 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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 { -- 2.39.5