]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] session-counters: correctly unbind the counters tracked by the backend
authorWilly Tarreau <w@1wt.eu>
Fri, 6 Aug 2010 18:11:05 +0000 (20:11 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 10 Aug 2010 16:04:16 +0000 (18:04 +0200)
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
include/types/session.h
src/proto_tcp.c

index f33f924d0f28ebba6405107328dbf1eb316acced..15f3fe744a2efc349538bda0c33801a641288385 100644 (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
index 79a837331916186f550be3cbc4dcea9125e48f9a..d1e54acff4a23a4d0aa11831f68e94018be6e067 100644 (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 */
 #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
index 588279181704899ed2c5798a9e3f2bd356825a85..301666f3c646b229f0f635ee305b666e09bc5ecd 100644 (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 {