TT#37500 Reset manual key count on key switch

When iterating through entry keys while searching for proper key,
reset manual key count when going to next entry key to avoid
writing beyond manaul key array.

Also fix memleak when deleting via table scan, where scanned
keys and manual keys were not properly deleted.

Also fix memleak when deleting in general, where type keys
were not properly deleted.

Change-Id: I60bb57ec95d863ace89a927341a9031bf67723ad
changes/86/21686/13
Andreas Granig 8 years ago
parent fe695b324a
commit a3b1703991

2
.gitignore vendored

@ -1 +1,3 @@
.pc
*~
.*.swp

@ -36,3 +36,4 @@ sipwise/rtpengine-balancing.patch
sipwise/0001-topos-reuse-uuid-for-requests-withing-dialog.patch
sipwise/0002-core-improve-to-header-check-guards-str-consists-of-.patch
sipwise/rls_fix_buffer.patch
sipwise/fix_db_redis_manual_key_issue.patch

@ -0,0 +1,189 @@
Index: kamailio/src/modules/db_redis/redis_dbase.c
===================================================================
--- kamailio.orig/src/modules/db_redis/redis_dbase.c
+++ kamailio/src/modules/db_redis/redis_dbase.c
@@ -236,6 +236,7 @@ static int db_redis_build_entry_manual_k
for (key = table->entry_keys; key; key = key->next) {
int subkey_found = 0;
int i;
+ *manual_key_count = 0;
LM_DBG("checking for existence of entry key '%.*s' in query to get manual key\n",
key->key.len, key->key.s);
for (i = 0; i < _n; ++i) {
@@ -1080,7 +1081,12 @@ static int db_redis_perform_query(const
RES_COL_N(*_r) = _nc;
if (!(*keys_count) && do_table_scan) {
- LM_DBG("performing full table scan\n");
+ LM_WARN("performing full table scan on table '%.*s' while performing query\n",
+ CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+ for(i = 0; i < _n; ++i) {
+ LM_WARN(" scan key %d is '%.*s'\n",
+ i, _k[i]->len, _k[i]->s);
+ }
if (db_redis_scan_query_keys(con, CON_TABLE(_h), _k, _n,
keys, keys_count,
manual_keys, manual_keys_count) != 0) {
@@ -1119,7 +1125,7 @@ static int db_redis_perform_query(const
LM_ERR("Failed to append redis command\n");
goto error;
}
- tmp = db_redis_key_unshift(&query_v);
+ tmp = db_redis_key_shift(&query_v);
if (tmp)
db_redis_key_free(&tmp);
@@ -1232,10 +1238,10 @@ error:
static int db_redis_perform_delete(const db1_con_t* _h, km_redis_con_t *con, const db_key_t* _k,
const db_val_t* _v, const db_op_t *_op, const int _n,
- redis_key_t *keys, int keys_count,
- int *manual_keys, int manual_keys_count, int do_table_scan) {
+ redis_key_t **keys, int *keys_count,
+ int **manual_keys, int *manual_keys_count, int do_table_scan) {
- int j = 0;
+ int i = 0, j = 0;
redis_key_t *k = NULL;
int type_keys_count = 0;
int all_type_keys_count = 0;
@@ -1249,11 +1255,16 @@ static int db_redis_perform_delete(const
db_key_t *db_keys = NULL;
redis_key_t *type_key;
- if (!keys_count && do_table_scan) {
- LM_DBG("performing full table scan\n");
+ if (!*keys_count && do_table_scan) {
+ LM_WARN("performing full table scan on table '%.*s' while performing delete\n",
+ CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+ for(i = 0; i < _n; ++i) {
+ LM_WARN(" scan key %d is '%.*s'\n",
+ i, _k[i]->len, _k[i]->s);
+ }
if (db_redis_scan_query_keys(con, CON_TABLE(_h), _k, _n,
- &keys, &keys_count,
- &manual_keys, &manual_keys_count) != 0) {
+ keys, keys_count,
+ manual_keys, manual_keys_count) != 0) {
LM_ERR("failed to scan query keys\n");
goto error;
}
@@ -1270,7 +1281,7 @@ static int db_redis_perform_delete(const
}
LM_DBG("delete all keys\n");
- for (k = keys; k; k = k->next) {
+ for (k = *keys; k; k = k->next) {
redis_key_t *all_type_key;
str *key = &k->key;
redis_key_t *tmp = NULL;
@@ -1292,10 +1303,11 @@ static int db_redis_perform_delete(const
if (reply->integer == 0) {
LM_DBG("key does not exist in redis, skip deleting\n");
db_redis_free_reply(&reply);
+ db_redis_key_free(&query_v);
continue;
}
db_redis_free_reply(&reply);
- tmp = db_redis_key_unshift(&query_v);
+ tmp = db_redis_key_shift(&query_v);
if (tmp)
db_redis_key_free(&tmp);
@@ -1305,8 +1317,8 @@ static int db_redis_perform_delete(const
}
// add all manual keys to query
- for (j = 0; j < manual_keys_count; ++j) {
- int idx = manual_keys[j];
+ for (j = 0; j < *manual_keys_count; ++j) {
+ int idx = (*manual_keys)[j];
str *col = _k[idx];
if (db_redis_key_add_str(&query_v, col) != 0) {
@@ -1331,8 +1343,8 @@ static int db_redis_perform_delete(const
// manually filter non-matching replies
row_match = 1;
for (col = 0; col < reply->elements; ++col) {
- if (col < manual_keys_count) {
- int idx = manual_keys[col];
+ if (col < *manual_keys_count) {
+ int idx = (*manual_keys)[col];
db_key_t k = _k[idx];
db_val_t v = _v[idx];
db_op_t o = _op[idx];
@@ -1370,7 +1382,7 @@ static int db_redis_perform_delete(const
for (j = 0, all_type_key = all_type_keys; all_type_key; ++j, all_type_key = all_type_key->next) {
db_val_t *v = &(db_vals[j]);
str *key = &all_type_key->key;
- char *value = reply->element[manual_keys_count + j]->str;
+ char *value = reply->element[*manual_keys_count + j]->str;
int coltype = db_redis_schema_get_column_type(con, CON_TABLE(_h), key);
if (value == NULL) {
VAL_NULL(v) = 1;
@@ -1422,11 +1434,9 @@ static int db_redis_perform_delete(const
db_redis_check_reply(con, reply, error);
db_redis_free_reply(&reply);
}
-
- //db_redis_key_free(&type_keys);
LM_DBG("done with loop '%.*s'\n", k->key.len, k->key.s);
+ db_redis_key_free(&type_keys);
}
- db_redis_key_free(&type_keys);
db_redis_key_free(&all_type_keys);
db_redis_key_free(&query_v);
@@ -1461,7 +1471,12 @@ static int db_redis_perform_update(const
size_t col;
if (!(*keys_count) && do_table_scan) {
- LM_DBG("performing full table scan\n");
+ LM_WARN("performing full table scan on table '%.*s' while performing update\n",
+ CON_TABLE(_h)->len, CON_TABLE(_h)->s);
+ for(i = 0; i < _n; ++i) {
+ LM_WARN(" scan key %d is '%.*s'\n",
+ i, _k[i]->len, _k[i]->s);
+ }
if (db_redis_scan_query_keys(con, CON_TABLE(_h), _k, _n,
keys, keys_count,
manual_keys, manual_keys_count) != 0) {
@@ -2027,7 +2042,7 @@ int db_redis_delete(const db1_con_t* _h,
}
if (db_redis_perform_delete(_h, con, _k, _v, query_ops, _n,
- keys, keys_count, manual_keys, manual_keys_count, do_table_scan) != 0) {
+ &keys, &keys_count, &manual_keys, &manual_keys_count, do_table_scan) != 0) {
goto error;
}
Index: kamailio/src/modules/db_redis/redis_table.c
===================================================================
--- kamailio.orig/src/modules/db_redis/redis_table.c
+++ kamailio/src/modules/db_redis/redis_table.c
@@ -103,7 +103,7 @@ err:
return -1;
}
-redis_key_t * db_redis_key_unshift(redis_key_t **list) {
+redis_key_t * db_redis_key_shift(redis_key_t **list) {
redis_key_t *k;
k = *list;
Index: kamailio/src/modules/db_redis/redis_table.h
===================================================================
--- kamailio.orig/src/modules/db_redis/redis_table.h
+++ kamailio/src/modules/db_redis/redis_table.h
@@ -58,9 +58,9 @@ int db_redis_key_add_string(redis_key_t*
int db_redis_key_add_str(redis_key_t **list, const str* entry);
int db_redis_key_prepend_string(redis_key_t **list, const char* entry, int len);
int db_redis_key_list2arr(redis_key_t *list, char ***arr);
-redis_key_t * db_redis_key_unshift(redis_key_t **list);
+redis_key_t * db_redis_key_shift(redis_key_t **list);
void db_redis_key_free(redis_key_t **list);
int db_redis_keys_spec(char *spec);
-#endif /* _REDIS_TABLE_H_ */
\ No newline at end of file
+#endif /* _REDIS_TABLE_H_ */
Loading…
Cancel
Save