From: Willy Tarreau Date: Tue, 18 Aug 2015 15:15:20 +0000 (+0200) Subject: BUG/MEDIUM: counters: ensure that src_{inc,clr}_gpc0 creates a missing entry X-Git-Tag: v1.6-dev4~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f4eadd4830279f5ee83aa545728fb750f5c8185;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: counters: ensure that src_{inc,clr}_gpc0 creates a missing entry 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. --- diff --git a/src/stream.c b/src/stream.c index c745ecfc3e..82b07439aa 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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)