]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: counters: ensure that src_{inc,clr}_gpc0 creates a missing entry
authorWilly Tarreau <w@1wt.eu>
Tue, 18 Aug 2015 15:15:20 +0000 (17:15 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 18 Aug 2015 15:15:20 +0000 (17:15 +0200)
During 1.5-dev20 there was some code refactoring to make the src_* fetch
function use the same code as sc_*. Unfortunately this introduced a
regression where src_* doesn't create an entry anymore if it does not
exist in the table. The reason is that smp_fetch_sc_stkctr() only calls
stktable_lookup_key() while src_inc_*/src_clr_* used to make use of
stktable_update_key() which additionally create the entry if it does
not exist.

There's no point modifying the common function for these two exceptions,
so instead we now have a function dedicated to the creation of this entry
for src_* only. It is called when the entry didn't exist, so that requires
minimal modifications to existing code.

Thanks to Thierry Fournier for helping diagnose the issue.

This fix must be backported to 1.5.

src/stream.c

index c745ecfc3e3d4e90c899a05926f882342aa8d7c2..82b07439aad16d13a703f5875c5ff063ea8088ec 100644 (file)
@@ -2636,6 +2636,33 @@ smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg
        return stkptr;
 }
 
+/* same as smp_fetch_sc_stkctr() but dedicated to src_* and can create
+ * the entry if it doesn't exist yet. This is needed for a few fetch
+ * functions which need to create an entry, such as src_inc_gpc* and
+ * src_clr_gpc*.
+ */
+struct stkctr *
+smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
+{
+       static struct stkctr stkctr;
+       struct stktable_key *key;
+       struct connection *conn = objt_conn(sess->origin);
+
+       if (strncmp(kw, "src_", 4) != 0)
+               return NULL;
+
+       if (!conn)
+               return NULL;
+
+       key = addr_to_stktable_key(&conn->addr.from, args->data.prx->table.type);
+       if (!key)
+               return NULL;
+
+       stkctr.table = &args->data.prx->table;
+       stkctr_set_entry(&stkctr, stktable_update_key(stkctr.table, key));
+       return &stkctr;
+}
+
 /* set return a boolean indicating if the requested stream counter is
  * currently being tracked or not.
  * Supports being called as "sc[0-9]_tracked" only.
@@ -2716,6 +2743,10 @@ smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw
        smp->flags = SMP_F_VOL_TEST;
        smp->type = SMP_T_SINT;
        smp->data.sint = 0;
+
+       if (stkctr_entry(stkctr) == NULL)
+               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw);
+
        if (stkctr_entry(stkctr) != NULL) {
                void *ptr1,*ptr2;
 
@@ -2755,6 +2786,10 @@ smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw
        smp->flags = SMP_F_VOL_TEST;
        smp->type = SMP_T_SINT;
        smp->data.sint = 0;
+
+       if (stkctr_entry(stkctr) == NULL)
+               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw);
+
        if (stkctr_entry(stkctr) != NULL) {
                void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
                if (!ptr)