-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Fix Bug: redis_auth don't work with redis_db #458
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2837,20 +2837,23 @@ redis_handle_auth_req(struct msg *req, struct msg *rsp) | |
} | ||
|
||
rstatus_t | ||
redis_add_auth(struct context *ctx, struct conn *c_conn, struct conn *s_conn) | ||
redis_add_auth(struct context *ctx, struct conn *conn, struct server *server, int *sended) | ||
{ | ||
rstatus_t status; | ||
struct msg *msg; | ||
struct server_pool *pool; | ||
|
||
ASSERT(!s_conn->client && !s_conn->proxy); | ||
ASSERT(!conn_authenticated(s_conn)); | ||
ASSERT(!conn->client && !conn->proxy && conn->connected && conn->redis); | ||
ASSERT(sended); | ||
|
||
pool = c_conn->owner; | ||
pool = server->owner; | ||
if (!pool->require_auth) { | ||
return NC_OK; | ||
} | ||
|
||
msg = msg_get(c_conn, true, c_conn->redis); | ||
msg = msg_get(conn, true, conn->redis); | ||
if (msg == NULL) { | ||
c_conn->err = errno; | ||
conn->err = errno; | ||
return NC_ENOMEM; | ||
} | ||
|
||
|
@@ -2861,23 +2864,33 @@ redis_add_auth(struct context *ctx, struct conn *c_conn, struct conn *s_conn) | |
return status; | ||
} | ||
|
||
msg->type = MSG_REQ_REDIS_AUTH; | ||
msg->result = MSG_PARSE_OK; | ||
msg->swallow = 1; | ||
s_conn->enqueue_inq(ctx, s_conn, msg); | ||
s_conn->authenticated = 1; | ||
msg->owner = NULL; | ||
|
||
conn->authenticated = 1; | ||
|
||
/* enqueue as head and send */ | ||
req_server_enqueue_imsgq_head(ctx, conn, msg); | ||
*sended = 1; | ||
|
||
log_debug(LOG_NOTICE, "sent 'AUTH %s' to %s | %s", pool->redis_auth.data, | ||
pool->name.data, server->name.data); | ||
|
||
return NC_OK; | ||
} | ||
|
||
void | ||
redis_post_connect(struct context *ctx, struct conn *conn, struct server *server) | ||
rstatus_t | ||
redis_select_db(struct context *ctx, struct conn *conn, struct server *server, int *sended) | ||
{ | ||
rstatus_t status; | ||
struct server_pool *pool = server->owner; | ||
struct msg *msg; | ||
int digits; | ||
|
||
ASSERT(!conn->client && conn->connected); | ||
ASSERT(conn->redis); | ||
ASSERT(!conn->client && conn->connected && conn->redis); | ||
ASSERT(sended); | ||
|
||
/* | ||
* By default, every connection to redis uses the database DB 0. You | ||
|
@@ -2886,7 +2899,7 @@ redis_post_connect(struct context *ctx, struct conn *conn, struct server *server | |
* on a per pool basis in the configuration | ||
*/ | ||
if (pool->redis_db <= 0) { | ||
return; | ||
return NC_OK; | ||
} | ||
|
||
/* | ||
|
@@ -2896,14 +2909,15 @@ redis_post_connect(struct context *ctx, struct conn *conn, struct server *server | |
*/ | ||
msg = msg_get(conn, true, conn->redis); | ||
if (msg == NULL) { | ||
return; | ||
conn->err = errno; | ||
return NC_ENOMEM; | ||
} | ||
|
||
digits = (pool->redis_db >= 10) ? (int)log10(pool->redis_db) + 1 : 1; | ||
status = msg_prepend_format(msg, "*2\r\n$6\r\nSELECT\r\n$%d\r\n%d\r\n", digits, pool->redis_db); | ||
if (status != NC_OK) { | ||
msg_put(msg); | ||
return; | ||
return status; | ||
} | ||
msg->type = MSG_REQ_REDIS_SELECT; | ||
msg->result = MSG_PARSE_OK; | ||
|
@@ -2912,10 +2926,23 @@ redis_post_connect(struct context *ctx, struct conn *conn, struct server *server | |
|
||
/* enqueue as head and send */ | ||
req_server_enqueue_imsgq_head(ctx, conn, msg); | ||
msg_send(ctx, conn); | ||
*sended = 1; | ||
|
||
log_debug(LOG_NOTICE, "sent 'SELECT %d' to %s | %s", pool->redis_db, | ||
pool->name.data, server->name.data); | ||
|
||
return NC_OK; | ||
} | ||
|
||
void | ||
redis_post_connect(struct context *ctx, struct conn *conn, struct server *server) | ||
{ | ||
int sended = 0; | ||
redis_select_db(ctx, conn, server, &sended); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Oh, I see, both of these will set the new message to be the head of the queue. So I misread it at first, it's actually sending the command to add auth before selecting the db number. (though I assume moving the auth check out of req_forward was the actual fix) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Exactly |
||
redis_add_auth(ctx, conn, server, &sended); | ||
if (sended) { | ||
msg_send(ctx, conn); | ||
} | ||
} | ||
|
||
void | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: https://www.merriam-webster.com/dictionary/sent seems more appropriate for a variable name here and elsewhere.
I had a lot of other changes planned for 0.6.0 (including merging in the heartbeat, failover, sentinel patches #608) and it may or may not be necessary to refactor this after that
Unrelated: Is it possible to rebase and add an integration test of this
At a glance, it seems like the right approach? I assume calling SELECT before AUTH is allowed if it worked for you, not familliar with redis auth
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @TysonAndre
So basically calling SELECT before AUTH does not work in redis but the issue is what @charsyam mentioned
once the connection is authenticated we can change the redis db using the SELECT command and this PR does fix that, I've verified in testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this part. Makes sense.