From 3e60b11100cbc812b77029ca142b83ac7a314db1 Mon Sep 17 00:00:00 2001 From: Daniel Corbett Date: Sun, 27 May 2018 09:47:12 -0400 Subject: [PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters When using table_* converters ref_cnt was incremented and never decremented causing entries to not expire. The root cause appears to be that stktable_lookup_key() was called within all sample_conv_table_* functions which was incrementing ref_cnt and not decrementing after completion. Added stktable_release() to the end of each sample_conv_table_* function and reworked the end logic to ensure that ref_cnt is always decremented after use. This should be backported to 1.8 --- src/stick_table.c | 170 +++++++++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 84 deletions(-) diff --git a/src/stick_table.c b/src/stick_table.c index fcc6fe6ad..101a4e253 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -875,6 +875,7 @@ static int sample_conv_in_table(const struct arg *arg_p, struct sample *smp, voi smp->data.type = SMP_T_BOOL; smp->data.u.sint = !!ts; smp->flags = SMP_F_VOL_TEST; + stktable_release(t, ts); return 1; } @@ -907,12 +908,12 @@ static int sample_conv_table_bytes_in_rate(const struct arg *arg_p, struct sampl return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_BYTES_IN_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate), + t->data_arg[STKTABLE_DT_BYTES_IN_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate), - t->data_arg[STKTABLE_DT_BYTES_IN_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -944,11 +945,11 @@ static int sample_conv_table_conn_cnt(const struct arg *arg_p, struct sample *sm return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CNT); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, conn_cnt); - smp->data.u.sint = stktable_data_cast(ptr, conn_cnt); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -980,11 +981,11 @@ static int sample_conv_table_conn_cur(const struct arg *arg_p, struct sample *sm return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CUR); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, conn_cur); - smp->data.u.sint = stktable_data_cast(ptr, conn_cur); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1016,12 +1017,12 @@ static int sample_conv_table_conn_rate(const struct arg *arg_p, struct sample *s return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate), + t->data_arg[STKTABLE_DT_CONN_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate), - t->data_arg[STKTABLE_DT_CONN_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1053,12 +1054,12 @@ static int sample_conv_table_bytes_out_rate(const struct arg *arg_p, struct samp return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_BYTES_OUT_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate), + t->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate), - t->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1090,11 +1091,11 @@ static int sample_conv_table_gpt0(const struct arg *arg_p, struct sample *smp, v return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPT0); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, gpt0); - smp->data.u.sint = stktable_data_cast(ptr, gpt0); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1126,11 +1127,11 @@ static int sample_conv_table_gpc0(const struct arg *arg_p, struct sample *smp, v return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPC0); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, gpc0); - smp->data.u.sint = stktable_data_cast(ptr, gpc0); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1162,12 +1163,12 @@ static int sample_conv_table_gpc0_rate(const struct arg *arg_p, struct sample *s return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPC0_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate), + t->data_arg[STKTABLE_DT_GPC0_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate), - t->data_arg[STKTABLE_DT_GPC0_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1199,11 +1200,11 @@ static int sample_conv_table_gpc1(const struct arg *arg_p, struct sample *smp, v return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPC1); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, gpc1); - smp->data.u.sint = stktable_data_cast(ptr, gpc1); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1235,12 +1236,12 @@ static int sample_conv_table_gpc1_rate(const struct arg *arg_p, struct sample *s return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPC1_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc1_rate), + t->data_arg[STKTABLE_DT_GPC1_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc1_rate), - t->data_arg[STKTABLE_DT_GPC1_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1272,11 +1273,11 @@ static int sample_conv_table_http_err_cnt(const struct arg *arg_p, struct sample return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_CNT); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt); - smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1308,12 +1309,12 @@ static int sample_conv_table_http_err_rate(const struct arg *arg_p, struct sampl return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate), + t->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate), - t->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1345,11 +1346,11 @@ static int sample_conv_table_http_req_cnt(const struct arg *arg_p, struct sample return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_REQ_CNT); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt); - smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1381,12 +1382,12 @@ static int sample_conv_table_http_req_rate(const struct arg *arg_p, struct sampl return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_REQ_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate), + t->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate), - t->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1418,11 +1419,11 @@ static int sample_conv_table_kbytes_in(const struct arg *arg_p, struct sample *s return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_BYTES_IN_CNT); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, bytes_in_cnt) >> 10; - smp->data.u.sint = stktable_data_cast(ptr, bytes_in_cnt) >> 10; - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1454,11 +1455,11 @@ static int sample_conv_table_kbytes_out(const struct arg *arg_p, struct sample * return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_BYTES_OUT_CNT); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, bytes_out_cnt) >> 10; - smp->data.u.sint = stktable_data_cast(ptr, bytes_out_cnt) >> 10; - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1490,11 +1491,11 @@ static int sample_conv_table_server_id(const struct arg *arg_p, struct sample *s return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_SERVER_ID); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, server_id); - smp->data.u.sint = stktable_data_cast(ptr, server_id); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1526,11 +1527,11 @@ static int sample_conv_table_sess_cnt(const struct arg *arg_p, struct sample *sm return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_SESS_CNT); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = stktable_data_cast(ptr, sess_cnt); - smp->data.u.sint = stktable_data_cast(ptr, sess_cnt); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1562,12 +1563,12 @@ static int sample_conv_table_sess_rate(const struct arg *arg_p, struct sample *s return 1; ptr = stktable_data_ptr(t, ts, STKTABLE_DT_SESS_RATE); - if (!ptr) - return 0; /* parameter not stored */ + if (ptr) + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate), + t->data_arg[STKTABLE_DT_SESS_RATE].u); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate), - t->data_arg[STKTABLE_DT_SESS_RATE].u); - return 1; + stktable_release(t, ts); + return !!ptr; } /* Casts sample to the type of the table specified in arg(0), and looks @@ -1597,6 +1598,7 @@ static int sample_conv_table_trackers(const struct arg *arg_p, struct sample *sm if (ts) smp->data.u.sint = ts->ref_cnt; + stktable_release(t, ts); return 1; }