commit eb83588: [Rework] Redis_pool: fix issues found
Vsevolod Stakhov
vsevolod at highsecure.ru
Sun Sep 12 11:42:04 UTC 2021
Author: Vsevolod Stakhov
Date: 2021-09-12 12:27:47 +0100
URL: https://github.com/rspamd/rspamd/commit/eb8358834ce9f393b22c94e75837ae664e14d471
[Rework] Redis_pool: fix issues found
---
src/libserver/redis_pool.cxx | 54 ++++++++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/src/libserver/redis_pool.cxx b/src/libserver/redis_pool.cxx
index 9053cc0e7..a3c5a7ebb 100644
--- a/src/libserver/redis_pool.cxx
+++ b/src/libserver/redis_pool.cxx
@@ -69,20 +69,17 @@ struct redis_pool_connection {
gchar tag[MEMPOOL_UID_LEN];
auto schedule_timeout() -> void;
-
~redis_pool_connection();
explicit redis_pool_connection(redis_pool *_pool,
redis_pool_elt *_elt,
- const char *db,
- const char *password,
+ const std::string &db,
+ const std::string &password,
struct redisAsyncContext *_ctx);
private:
static auto redis_conn_timeout_cb(EV_P_ ev_timer *w, int revents) -> void;
-
static auto redis_quit_cb(redisAsyncContext *c, void *r, void *priv) -> void;
-
static auto redis_on_disconnect(const struct redisAsyncContext *ac, int status) -> auto;
};
@@ -109,10 +106,17 @@ public:
explicit redis_pool_elt(redis_pool *_pool,
const gchar *_db, const gchar *_password,
const char *_ip, int _port)
- : pool(_pool), ip(_ip), db(_db), password(_password), port(_port),
+ : pool(_pool), ip(_ip), port(_port),
key(redis_pool_elt::make_key(_db, _password, _ip, _port))
{
is_unix = ip[0] == '.' || ip[0] == '/';
+
+ if (_db) {
+ db = _db;
+ }
+ if (_password) {
+ password = _password;
+ }
}
auto new_connection() -> redisAsyncContext *;
@@ -157,6 +161,10 @@ public:
return active.size();
}
+ ~redis_pool_elt() {
+ rspamd_explicit_memzero(password.data(), password.size());
+ }
+
private:
auto redis_async_new() -> redisAsyncContext *
{
@@ -186,9 +194,9 @@ class redis_pool {
static constexpr const unsigned default_max_conns = 100;
/* We want to have references integrity */
- robin_hood::unordered_node_map<redis_pool_key_t, redis_pool_elt> elts_by_key;
robin_hood::unordered_flat_map<redisAsyncContext *,
redis_pool_connection *> conns_by_ctx;
+ robin_hood::unordered_node_map<redis_pool_key_t, redis_pool_elt> elts_by_key;
public:
double timeout = default_timeout;
unsigned max_conns = default_max_conns;
@@ -363,8 +371,8 @@ redis_pool_connection::schedule_timeout() -> void
redis_pool_connection::redis_pool_connection(redis_pool *_pool,
redis_pool_elt *_elt,
- const char *db,
- const char *password,
+ const std::string &db,
+ const std::string &password,
struct redisAsyncContext *_ctx)
: ctx(_ctx), elt(_elt), pool(_pool)
{
@@ -378,13 +386,13 @@ redis_pool_connection::redis_pool_connection(redis_pool *_pool,
redisLibevAttach(pool->event_loop, ctx);
redisAsyncSetDisconnectCallback(ctx, redis_pool_connection::redis_on_disconnect);
- if (password) {
- redisAsyncCommand(ctx, NULL, NULL,
- "AUTH %s", password);
+ if (!password.empty()) {
+ redisAsyncCommand(ctx, nullptr, nullptr,
+ "AUTH %s", password.c_str());
}
- if (db) {
- redisAsyncCommand(ctx, NULL, NULL,
- "SELECT %s", db);
+ if (!db.empty()) {
+ redisAsyncCommand(ctx, nullptr, nullptr,
+ "SELECT %s", db.c_str());
}
}
@@ -392,7 +400,8 @@ auto
redis_pool_elt::new_connection() -> redisAsyncContext *
{
if (!inactive.empty()) {
- auto &&conn = std::move(inactive.back());
+ decltype(inactive)::value_type conn;
+ conn.swap(inactive.back());
inactive.pop_back();
g_assert (conn->state != RSPAMD_REDIS_POOL_CONN_ACTIVE);
@@ -421,6 +430,8 @@ redis_pool_elt::new_connection() -> redisAsyncContext *
ip.c_str(), port, conn->ctx);
active.emplace_front(std::move(conn));
active.front()->elt_pos = active.begin();
+
+ return active.front()->ctx;
}
}
else {
@@ -463,8 +474,9 @@ redis_pool::new_connection(const gchar *db, const gchar *password,
}
else {
/* Need to create a pool */
- auto nelt = elts_by_key.emplace(key,
- redis_pool_elt{this, db, password, ip, port});
+ auto nelt = elts_by_key.emplace(std::piecewise_construct,
+ std::forward_as_tuple(key),
+ std::forward_as_tuple(this, db, password, ip, port));
return nelt.first->second.new_connection();
}
@@ -481,7 +493,6 @@ auto redis_pool::release_connection(redisAsyncContext *ctx,
if (ctx->err != REDIS_OK) {
/* We need to terminate connection forcefully */
msg_debug_rpool ("closed connection %p due to an error", conn->ctx);
- conn->elt->release_active(conn);
}
else {
if (how == RSPAMD_REDIS_RELEASE_DEFAULT) {
@@ -492,11 +503,12 @@ auto redis_pool::release_connection(redisAsyncContext *ctx,
conn->elt->move_to_inactive(conn);
conn->schedule_timeout();
msg_debug_rpool("mark connection %p inactive", conn->ctx);
+
+ return;
}
else {
msg_debug_rpool("closed connection %p due to callbacks left",
conn->ctx);
- conn->elt->release_active(conn);
}
}
else {
@@ -508,8 +520,6 @@ auto redis_pool::release_connection(redisAsyncContext *ctx,
msg_debug_rpool("closed connection %p due to explicit termination",
conn->ctx);
}
-
- conn->elt->release_active(conn);
}
}
More information about the Commits
mailing list