"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib-dict/dict-redis.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

dict-redis.c  (dovecot-2.3.16):dict-redis.c  (dovecot-2.3.17)
skipping to change at line 50 skipping to change at line 50
}; };
struct redis_dict_reply { struct redis_dict_reply {
unsigned int reply_count; unsigned int reply_count;
dict_transaction_commit_callback_t *callback; dict_transaction_commit_callback_t *callback;
void *context; void *context;
}; };
struct redis_dict { struct redis_dict {
struct dict dict; struct dict dict;
char *username, *password, *key_prefix, *expire_value; char *password, *key_prefix, *expire_value;
unsigned int timeout_msecs, db_id; unsigned int timeout_msecs, db_id;
struct redis_connection conn; struct redis_connection conn;
ARRAY(enum redis_input_state) input_states; ARRAY(enum redis_input_state) input_states;
ARRAY(struct redis_dict_reply) replies; ARRAY(struct redis_dict_reply) replies;
bool connected; bool connected;
bool transaction_open; bool transaction_open;
bool db_id_set; bool db_id_set;
skipping to change at line 443 skipping to change at line 443
connection_init_client_ip(redis_connections, &dict->conn.conn, connection_init_client_ip(redis_connections, &dict->conn.conn,
NULL, &ip, port); NULL, &ip, port);
} }
event_set_append_log_prefix(dict->conn.conn.event, "redis: "); event_set_append_log_prefix(dict->conn.conn.event, "redis: ");
dict->dict = *driver; dict->dict = *driver;
dict->conn.last_reply = str_new(default_pool, 256); dict->conn.last_reply = str_new(default_pool, 256);
dict->conn.dict = dict; dict->conn.dict = dict;
i_array_init(&dict->input_states, 4); i_array_init(&dict->input_states, 4);
i_array_init(&dict->replies, 4); i_array_init(&dict->replies, 4);
if (strchr(set->username, DICT_USERNAME_SEPARATOR) == NULL)
dict->username = i_strdup(set->username);
else {
/* escape the username */
dict->username = i_strdup(redis_escape_username(set->username));
}
*dict_r = &dict->dict; *dict_r = &dict->dict;
return 0; return 0;
} }
static void redis_dict_deinit(struct dict *_dict) static void redis_dict_deinit(struct dict *_dict)
{ {
struct redis_dict *dict = (struct redis_dict *)_dict; struct redis_dict *dict = (struct redis_dict *)_dict;
if (array_count(&dict->input_states) > 0) { if (array_count(&dict->input_states) > 0) {
i_assert(dict->connected); i_assert(dict->connected);
redis_wait(dict); redis_wait(dict);
} }
connection_deinit(&dict->conn.conn); connection_deinit(&dict->conn.conn);
str_free(&dict->conn.last_reply); str_free(&dict->conn.last_reply);
array_free(&dict->replies); array_free(&dict->replies);
array_free(&dict->input_states); array_free(&dict->input_states);
i_free(dict->expire_value); i_free(dict->expire_value);
i_free(dict->key_prefix); i_free(dict->key_prefix);
i_free(dict->password); i_free(dict->password);
i_free(dict->username);
i_free(dict); i_free(dict);
if (redis_connections->connections == NULL) if (redis_connections->connections == NULL)
connection_list_deinit(&redis_connections); connection_list_deinit(&redis_connections);
} }
static void redis_dict_wait(struct dict *_dict) static void redis_dict_wait(struct dict *_dict)
{ {
struct redis_dict *dict = (struct redis_dict *)_dict; struct redis_dict *dict = (struct redis_dict *)_dict;
skipping to change at line 493 skipping to change at line 486
static void redis_dict_lookup_timeout(struct redis_dict *dict) static void redis_dict_lookup_timeout(struct redis_dict *dict)
{ {
const char *reason = t_strdup_printf( const char *reason = t_strdup_printf(
"redis: Lookup timed out in %u.%03u secs", "redis: Lookup timed out in %u.%03u secs",
dict->timeout_msecs/1000, dict->timeout_msecs%1000); dict->timeout_msecs/1000, dict->timeout_msecs%1000);
redis_disconnected(&dict->conn, reason); redis_disconnected(&dict->conn, reason);
} }
static const char * static const char *
redis_dict_get_full_key(struct redis_dict *dict, const char *key) redis_dict_get_full_key(struct redis_dict *dict, const char *username,
const char *key)
{ {
const char *username_sp = strchr(username, DICT_USERNAME_SEPARATOR);
if (str_begins(key, DICT_PATH_SHARED)) if (str_begins(key, DICT_PATH_SHARED))
key += strlen(DICT_PATH_SHARED); key += strlen(DICT_PATH_SHARED);
else if (str_begins(key, DICT_PATH_PRIVATE)) { else if (str_begins(key, DICT_PATH_PRIVATE)) {
key = t_strdup_printf("%s%c%s", dict->username, key = t_strdup_printf("%s%c%s",
username_sp == NULL ? username :
redis_escape_username(username),
DICT_USERNAME_SEPARATOR, DICT_USERNAME_SEPARATOR,
key + strlen(DICT_PATH_PRIVATE)); key + strlen(DICT_PATH_PRIVATE));
} else { } else {
i_unreached(); i_unreached();
} }
if (*dict->key_prefix != '\0') if (*dict->key_prefix != '\0')
key = t_strconcat(dict->key_prefix, key, NULL); key = t_strconcat(dict->key_prefix, key, NULL);
return key; return key;
} }
skipping to change at line 540 skipping to change at line 538
/* 0 is the default */ /* 0 is the default */
return; return;
} }
db_str = dec2str(dict->db_id); db_str = dec2str(dict->db_id);
cmd = t_strdup_printf("*2\r\n$6\r\nSELECT\r\n$%d\r\n%s\r\n", cmd = t_strdup_printf("*2\r\n$6\r\nSELECT\r\n$%d\r\n%s\r\n",
(int)strlen(db_str), db_str); (int)strlen(db_str), db_str);
o_stream_nsend_str(dict->conn.conn.output, cmd); o_stream_nsend_str(dict->conn.conn.output, cmd);
redis_input_state_add(dict, REDIS_INPUT_STATE_SELECT); redis_input_state_add(dict, REDIS_INPUT_STATE_SELECT);
} }
static int redis_dict_lookup(struct dict *_dict, pool_t pool, const char *key, static int redis_dict_lookup(struct dict *_dict,
const struct dict_op_settings *set,
pool_t pool, const char *key,
const char **value_r, const char **error_r) const char **value_r, const char **error_r)
{ {
struct redis_dict *dict = (struct redis_dict *)_dict; struct redis_dict *dict = (struct redis_dict *)_dict;
struct timeout *to; struct timeout *to;
const char *cmd; const char *cmd;
key = redis_dict_get_full_key(dict, key); key = redis_dict_get_full_key(dict, set->username, key);
dict->conn.value_received = FALSE; dict->conn.value_received = FALSE;
dict->conn.value_not_found = FALSE; dict->conn.value_not_found = FALSE;
i_assert(dict->dict.ioloop == NULL); i_assert(dict->dict.ioloop == NULL);
dict->dict.prev_ioloop = current_ioloop; dict->dict.prev_ioloop = current_ioloop;
dict->dict.ioloop = io_loop_create(); dict->dict.ioloop = io_loop_create();
connection_switch_ioloop(&dict->conn.conn); connection_switch_ioloop(&dict->conn.conn);
skipping to change at line 746 skipping to change at line 746
redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI); redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI);
ctx->cmd_count++; ctx->cmd_count++;
} }
static void redis_set(struct dict_transaction_context *_ctx, static void redis_set(struct dict_transaction_context *_ctx,
const char *key, const char *value) const char *key, const char *value)
{ {
struct redis_dict_transaction_context *ctx = struct redis_dict_transaction_context *ctx =
(struct redis_dict_transaction_context *)_ctx; (struct redis_dict_transaction_context *)_ctx;
struct redis_dict *dict = (struct redis_dict *)_ctx->dict; struct redis_dict *dict = (struct redis_dict *)_ctx->dict;
const struct dict_op_settings_private *set = &_ctx->set;
string_t *cmd; string_t *cmd;
if (redis_check_transaction(ctx) < 0) if (redis_check_transaction(ctx) < 0)
return; return;
key = redis_dict_get_full_key(dict, key); key = redis_dict_get_full_key(dict, set->username, key);
cmd = t_str_new(128); cmd = t_str_new(128);
str_printfa(cmd, "*3\r\n$3\r\nSET\r\n$%u\r\n%s\r\n$%u\r\n%s\r\n", str_printfa(cmd, "*3\r\n$3\r\nSET\r\n$%u\r\n%s\r\n$%u\r\n%s\r\n",
(unsigned int)strlen(key), key, (unsigned int)strlen(key), key,
(unsigned int)strlen(value), value); (unsigned int)strlen(value), value);
redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI); redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI);
ctx->cmd_count++; ctx->cmd_count++;
redis_append_expire(ctx, cmd, key); redis_append_expire(ctx, cmd, key);
if (o_stream_send(dict->conn.conn.output, str_data(cmd), str_len(cmd)) < 0) { if (o_stream_send(dict->conn.conn.output, str_data(cmd), str_len(cmd)) < 0) {
ctx->error = i_strdup_printf("write() failed: %s", ctx->error = i_strdup_printf("write() failed: %s",
o_stream_get_error(dict->conn.conn.output)); o_stream_get_error(dict->conn.conn.output));
} }
} }
static void redis_unset(struct dict_transaction_context *_ctx, static void redis_unset(struct dict_transaction_context *_ctx,
const char *key) const char *key)
{ {
struct redis_dict_transaction_context *ctx = struct redis_dict_transaction_context *ctx =
(struct redis_dict_transaction_context *)_ctx; (struct redis_dict_transaction_context *)_ctx;
struct redis_dict *dict = (struct redis_dict *)_ctx->dict; struct redis_dict *dict = (struct redis_dict *)_ctx->dict;
const struct dict_op_settings_private *set = &_ctx->set;
const char *cmd; const char *cmd;
if (redis_check_transaction(ctx) < 0) if (redis_check_transaction(ctx) < 0)
return; return;
key = redis_dict_get_full_key(dict, key); key = redis_dict_get_full_key(dict, set->username, key);
cmd = t_strdup_printf("*2\r\n$3\r\nDEL\r\n$%u\r\n%s\r\n", cmd = t_strdup_printf("*2\r\n$3\r\nDEL\r\n$%u\r\n%s\r\n",
(unsigned int)strlen(key), key); (unsigned int)strlen(key), key);
if (o_stream_send_str(dict->conn.conn.output, cmd) < 0) { if (o_stream_send_str(dict->conn.conn.output, cmd) < 0) {
ctx->error = i_strdup_printf("write() failed: %s", ctx->error = i_strdup_printf("write() failed: %s",
o_stream_get_error(dict->conn.conn.output)); o_stream_get_error(dict->conn.conn.output));
} }
redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI); redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI);
ctx->cmd_count++; ctx->cmd_count++;
} }
static void redis_atomic_inc(struct dict_transaction_context *_ctx, static void redis_atomic_inc(struct dict_transaction_context *_ctx,
const char *key, long long diff) const char *key, long long diff)
{ {
struct redis_dict_transaction_context *ctx = struct redis_dict_transaction_context *ctx =
(struct redis_dict_transaction_context *)_ctx; (struct redis_dict_transaction_context *)_ctx;
struct redis_dict *dict = (struct redis_dict *)_ctx->dict; struct redis_dict *dict = (struct redis_dict *)_ctx->dict;
const struct dict_op_settings_private *set = &_ctx->set;
const char *diffstr; const char *diffstr;
string_t *cmd; string_t *cmd;
if (redis_check_transaction(ctx) < 0) if (redis_check_transaction(ctx) < 0)
return; return;
key = redis_dict_get_full_key(dict, key); key = redis_dict_get_full_key(dict, set->username, key);
diffstr = t_strdup_printf("%lld", diff); diffstr = t_strdup_printf("%lld", diff);
cmd = t_str_new(128); cmd = t_str_new(128);
str_printfa(cmd, "*3\r\n$6\r\nINCRBY\r\n$%u\r\n%s\r\n$%u\r\n%s\r\n", str_printfa(cmd, "*3\r\n$6\r\nINCRBY\r\n$%u\r\n%s\r\n$%u\r\n%s\r\n",
(unsigned int)strlen(key), key, (unsigned int)strlen(key), key,
(unsigned int)strlen(diffstr), diffstr); (unsigned int)strlen(diffstr), diffstr);
redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI); redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI);
ctx->cmd_count++; ctx->cmd_count++;
redis_append_expire(ctx, cmd, key); redis_append_expire(ctx, cmd, key);
if (o_stream_send(dict->conn.conn.output, str_data(cmd), str_len(cmd)) < 0) { if (o_stream_send(dict->conn.conn.output, str_data(cmd), str_len(cmd)) < 0) {
ctx->error = i_strdup_printf("write() failed: %s", ctx->error = i_strdup_printf("write() failed: %s",
 End of changes. 14 change blocks. 
15 lines changed or deleted 18 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)