Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for volatile keys #460

Merged
merged 3 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [21.10] (unreleased)

### Added

- Add support for volatile keys. [#460](https://github.com/greenbone/gvm-libs/pull/460)

### Changed
### Removed
### Fixed
Expand Down
153 changes: 151 additions & 2 deletions util/kb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,100 @@ redis_del_items (kb_t kb, const char *name)
return rc;
}

/**
* @brief Insert (append) a new unique and volatile entry under a given name.
*
* @param[in] kb KB handle where to store the item.
* @param[in] name Item name.
* @param[in] str Item value.
* @param[in] expire Item expire.
* @param[in] len Value length. Used for blobs.
* @param[in] pos Which position the value is appended to. 0 for right,
* 1 for left position in the list.
*
* @return 0 on success, -1 on error.
*/
static int
redis_add_str_unique_volatile (kb_t kb, const char *name, const char *str,
int expire, size_t len, int pos)
{
struct kb_redis *kbr;
redisReply *rep = NULL;
int rc = 0;
redisContext *ctx;

kbr = redis_kb (kb);
if (get_redis_ctx (kbr) < 0)
return -1;
ctx = kbr->rctx;

/* Some VTs still rely on values being unique (ie. a value inserted multiple
* times, will only be present once.)
* Once these are fixed, the LREM becomes redundant and should be removed.
*/
if (len == 0)
{
redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
redisAppendCommand (ctx, "%s %s %s", pos ? "LPUSH" : "RPUSH", name, str);
redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
/* Check LREM reply. */
redisGetReply (ctx, (void **) &rep);
if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
g_debug ("Key '%s' already contained value '%s'", name, str);
freeReplyObject (rep);
/* Check PUSH reply. */
redisGetReply (ctx, (void **) &rep);
if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
{
rc = -1;
goto out;
}
/* Check EXPIRE reply. */
redisGetReply (ctx, (void **) &rep);
if (rep == NULL || rep->type == REDIS_REPLY_ERROR
|| (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
{
g_warning ("%s: Not able to set expire", __func__);
rc = -1;
goto out;
}
}
else
{
redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
redisAppendCommand (ctx, "%s %s %b", pos ? "LPUSH" : "RPUSH", name, str,
len);
redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
/* Check LREM reply. */
redisGetReply (ctx, (void **) &rep);
if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
g_debug ("Key '%s' already contained string '%s'", name, str);
freeReplyObject (rep);
/* Check PUSH reply. */
redisGetReply (ctx, (void **) &rep);
if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
{
rc = -1;
goto out;
}
/* Check EXPIRE reply. */
redisGetReply (ctx, (void **) &rep);
if (rep == NULL || rep->type == REDIS_REPLY_ERROR
|| (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
{
g_warning ("%s: Not able to set expire", __func__);
rc = -1;
goto out;
}
}

out:
if (rep != NULL)
freeReplyObject (rep);

return rc;
}

/**
* @brief Insert (append) a new unique entry under a given name.
*
Expand Down Expand Up @@ -1279,6 +1373,60 @@ redis_set_str (kb_t kb, const char *name, const char *val, size_t len)
return rc;
}

/**
* @brief Insert (append) a new unique entry under a given name.
*
* @param[in] kb KB handle where to store the item.
* @param[in] name Item name.
* @param[in] val Item value.
* @param[in] expire Item expire.
*
* @return 0 on success, non-null on error.
*/
static int
redis_add_int_unique_volatile (kb_t kb, const char *name, int val, int expire)
{
struct kb_redis *kbr;
redisReply *rep;
int rc = 0;
redisContext *ctx;

kbr = redis_kb (kb);
if (get_redis_ctx (kbr) < 0)
return -1;
ctx = kbr->rctx;
redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
redisAppendCommand (ctx, "RPUSH %s %d", name, val);
redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
/* Check LREM reply. */
redisGetReply (ctx, (void **) &rep);
if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
g_debug ("Key '%s' already contained integer '%d'", name, val);
freeReplyObject (rep);
/* Check PUSH reply. */
redisGetReply (ctx, (void **) &rep);
if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
{
rc = -1;
goto out;
}
/* Check EXPIRE reply. */
redisGetReply (ctx, (void **) &rep);
if (rep == NULL || rep->type == REDIS_REPLY_ERROR
|| (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
{
g_warning ("%s: Not able to set expire", __func__);
rc = -1;
goto out;
}

out:
if (rep != NULL)
freeReplyObject (rep);

return rc;
}

/**
* @brief Insert (append) a new unique entry under a given name.
*
Expand Down Expand Up @@ -1645,17 +1793,18 @@ static const struct kb_operations KBRedisOperations = {
.kb_count = redis_count,
.kb_add_str = redis_add_str,
.kb_add_str_unique = redis_add_str_unique,
.kb_add_str_unique_volatile = redis_add_str_unique_volatile,
.kb_set_str = redis_set_str,
.kb_add_int = redis_add_int,
.kb_add_int_unique = redis_add_int_unique,
.kb_add_int_unique_volatile = redis_add_int_unique_volatile,
.kb_set_int = redis_set_int,
.kb_add_nvt = redis_add_nvt,
.kb_del_items = redis_del_items,
.kb_lnk_reset = redis_lnk_reset,
.kb_save = redis_save,
.kb_flush = redis_flush_all,
.kb_direct_conn = redis_direct_conn,
.kb_get_kb_index = redis_get_kb_index,
};
.kb_get_kb_index = redis_get_kb_index};

const struct kb_operations *KBDefaultOperations = &KBRedisOperations;
54 changes: 54 additions & 0 deletions util/kb.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ struct kb_operations
* unique entry under a given name.
*/
int (*kb_add_str_unique) (kb_t, const char *, const char *, size_t, int);
/**
* Function provided by an implementation to insert (append) a new
* unique and volatile entry under a given name.
*/
int (*kb_add_str_unique_volatile) (kb_t, const char *, const char *, int,
size_t, int);
/**
* Function provided by an implementation to get (replace) a new entry
* under a given name.
Expand All @@ -199,6 +205,11 @@ struct kb_operations
* unique entry under a given name.
*/
int (*kb_add_int_unique) (kb_t, const char *, int);
/**
* Fucntion provided by an implementation to insert (append) a new
* unique and volatile entry under a given name.
*/
int (*kb_add_int_unique_volatile) (kb_t, const char *, int, int);
/**
* Function provided by an implementation to get (replace) a new entry
* under a given name.
Expand Down Expand Up @@ -473,6 +484,29 @@ kb_item_add_str_unique (kb_t kb, const char *name, const char *str, size_t len,
return kb->kb_ops->kb_add_str_unique (kb, name, str, len, pos);
}

/**
* @brief Insert (append) a new unique and volatile entry under a given name.
* @param[in] kb Reference to a kb_t to initialize.
* @param[in] name Item name.
* @param[in] val Item value.
* @param[in] expire Item expire.
* @param[in] len Value length. Used for blobs.
* @param[in] pos Which position the value is appended to. 0 for right, 1 for
* left position in the list.
* @return 0 on success, -1 on error.
*/
static inline int
kb_add_str_unique_volatile (kb_t kb, const char *name, const char *str,
int expire, size_t len, int pos)
{
assert (kb);
assert (KBDefaultOperations);
assert (KBDefaultOperations->kb_add_str_unique_volatile);

return KBDefaultOperations->kb_add_str_unique_volatile (kb, name, str, expire,
len, pos);
}

/**
* @brief Set (replace) a new entry under a given name.
* @param[in] kb KB handle where to store the item.
Expand Down Expand Up @@ -525,6 +559,26 @@ kb_item_add_int_unique (kb_t kb, const char *name, int val)
return kb->kb_ops->kb_add_int_unique (kb, name, val);
}

/**
* @brief Insert (append) a new unique and volatile entry under a given name.
* @param[in] kb Reference to a kb_t to initialize.
* @param[in] name Item name.
* @param[in] val Item value.
* @param[in] expire Item expire.
*
* @return 0 on success, -1 on error.
*/
static inline int
kb_add_int_unique_volatile (kb_t kb, const char *name, int val, int expire)
{
assert (kb);
assert (KBDefaultOperations);
assert (KBDefaultOperations->kb_add_int_unique_volatile);

return KBDefaultOperations->kb_add_int_unique_volatile (kb, name, val,
expire);
}

/**
* @brief Set (replace) a new entry under a given name.
* @param[in] kb KB handle where to store the item.
Expand Down