From b950074392e5bc0d83923c0bfbd9ee8380043d2d Mon Sep 17 00:00:00 2001 From: lizhiang Date: Wed, 9 Nov 2016 15:11:24 +0800 Subject: [PATCH] Support auth in redis cluster --- README.md | 4 +-- hircluster.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++----- hircluster.h | 7 +++-- net.c | 2 +- net.h | 2 +- 5 files changed, 80 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index bc69f55..49f38e0 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ int redisClusterAppendCommandArgv(redisClusterContext *cc, int argc, const char int redisClusterGetReply(redisClusterContext *cc, void **reply); void redisCLusterReset(redisClusterContext *cc); -redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags); +redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, const char *auth, int flags); int redisClusterAsyncSetConnectCallback(redisClusterAsyncContext *acc, redisConnectCallback *fn); int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn); int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, char *cmd, int len); @@ -185,7 +185,7 @@ should be checked after creation to see if there were errors creating the connec Because the connection that will be created is non-blocking, the kernel is not able to instantly return if the specified host and port is able to accept a connection. ```c -redisClusterAsyncContext *acc = redisClusterAsyncConnect("127.0.0.1:6379", HIRCLUSTER_FLAG_NULL); +redisClusterAsyncContext *acc = redisClusterAsyncConnect("127.0.0.1:6379", "auth", HIRCLUSTER_FLAG_NULL); if (acc->err) { printf("Error: %s\n", acc->errstr); // handle error diff --git a/hircluster.c b/hircluster.c index bbe2f2b..86ccc5e 100644 --- a/hircluster.c +++ b/hircluster.c @@ -11,6 +11,7 @@ #include "adlist.h" #include "hiarray.h" #include "command.h" +#include "net.h" #include "dict.c" #define REDIS_COMMAND_CLUSTER_NODES "CLUSTER NODES" @@ -1291,6 +1292,20 @@ cluster_update_route_by_addr(redisClusterContext *cc, goto error; } +#if 1 + // Add auth + if(cc->auth){ + reply = redisCommand(c, "auth %s", cc->auth); + if(reply == NULL){ + __redisClusterSetError(cc,REDIS_ERR_OTHER, + "Command(auth XXXXX) reply error(NULL)."); + goto error; + } + + freeReplyObject(reply); + } +#endif + if(cc->flags & HIRCLUSTER_FLAG_ROUTE_USE_SLOTS){ reply = redisCommand(c, REDIS_COMMAND_CLUSTER_SLOTS); if(reply == NULL){ @@ -1998,6 +2013,7 @@ static redisClusterContext *redisClusterContextInit(void) { cc->err = 0; cc->errstr[0] = '\0'; + cc->auth[0] = '\0'; cc->ip = NULL; cc->port = 0; cc->flags = 0; @@ -2151,7 +2167,6 @@ static redisClusterContext *_redisClusterConnect(redisClusterContext *cc, const { return NULL; } - address = sdssplitlen(addrs, strlen(addrs), CLUSTER_ADDRESS_SEPARATOR, strlen(CLUSTER_ADDRESS_SEPARATOR), &address_count); @@ -2194,10 +2209,34 @@ redisClusterContext *redisClusterConnect(const char *addrs, int flags) { cc->flags |= flags; } - + return _redisClusterConnect(cc, addrs); } +redisClusterContext *redisClusterConnectWithAuth(const char *addrs, const char *auth, int flags) +{ + redisClusterContext *cc; + + cc = redisClusterContextInit(); + + if(cc == NULL) + { + return NULL; + } + + cc->flags |= REDIS_BLOCK; + if(flags) + { + cc->flags |= flags; + } + + if(auth) + { + memcpy(cc->auth, auth, strlen(auth)); + } + + return _redisClusterConnect(cc, addrs); +} redisClusterContext *redisClusterConnectWithTimeout( const char *addrs, const struct timeval tv, int flags) { @@ -2226,7 +2265,8 @@ redisClusterContext *redisClusterConnectWithTimeout( return _redisClusterConnect(cc, addrs); } -redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags) { +redisClusterContext *redisClusterConnectNonBlock(const char *addrs, + const char *auth, int flags) { redisClusterContext *cc; @@ -2242,7 +2282,12 @@ redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags) { { cc->flags |= flags; } - + + if(auth) + { + memcpy(cc->auth, auth, strlen(auth)); + } + return _redisClusterConnect(cc, addrs); } @@ -4044,7 +4089,7 @@ redisAsyncContext * actx_get_by_node(redisClusterAsyncContext *acc, cluster_node *node) { redisAsyncContext *ac; - + if(node == NULL) { return NULL; @@ -4089,6 +4134,25 @@ redisAsyncContext * actx_get_by_node(redisClusterAsyncContext *acc, node->acon = ac; +#if 1 + //Add auth + redisReply *reply = NULL; + ac->c.flags |= REDIS_BLOCK; + redisSetBlocking(&ac->c, 1); + if (acc->cc->auth) + { + reply = redisCommand(&ac->c, "auth %s", acc->cc->auth); + if(reply == NULL){ + __redisClusterSetError(acc->cc, REDIS_ERR_OTHER, + "Command(auth XXXXX) reply error(NULL)."); + } + + freeReplyObject(reply); + } + redisSetBlocking(&ac->c, 0); + ac->c.flags &= ~REDIS_BLOCK; + +#endif return ac; } @@ -4143,12 +4207,13 @@ static redisAsyncContext *actx_get_after_update_route_by_slot( return ac; } -redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags) { +redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, + const char *auth, int flags) { redisClusterContext *cc; redisClusterAsyncContext *acc; - cc = redisClusterConnectNonBlock(addrs, flags); + cc = redisClusterConnectNonBlock(addrs, auth, flags); if(cc == NULL) { return NULL; diff --git a/hircluster.h b/hircluster.h index 19aceae..6c4a06c 100644 --- a/hircluster.h +++ b/hircluster.h @@ -73,9 +73,9 @@ extern "C" { typedef struct redisClusterContext { int err; /* Error flags, 0 when there is no error */ char errstr[128]; /* String representation of error when applicable */ + char auth[128]; sds ip; int port; - int flags; enum redisConnectionType connection_type; @@ -98,9 +98,10 @@ typedef struct redisClusterContext { } redisClusterContext; redisClusterContext *redisClusterConnect(const char *addrs, int flags); +redisClusterContext *redisClusterConnectWithAuth(const char *addrs, const char *auth, int flags); redisClusterContext *redisClusterConnectWithTimeout(const char *addrs, const struct timeval tv, int flags); -redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags); +redisClusterContext *redisClusterConnectNonBlock(const char *addrs, const char *auth, int flags); void redisClusterFree(redisClusterContext *cc); @@ -158,7 +159,7 @@ typedef struct redisClusterAsyncContext { } redisClusterAsyncContext; -redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags); +redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, const char *auth, int flags); int redisClusterAsyncSetConnectCallback(redisClusterAsyncContext *acc, redisConnectCallback *fn); int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn); int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, char *cmd, int len); diff --git a/net.c b/net.c index 60a2dc7..caaf643 100644 --- a/net.c +++ b/net.c @@ -99,7 +99,7 @@ static int redisCreateSocket(redisContext *c, int type) { return REDIS_OK; } -static int redisSetBlocking(redisContext *c, int blocking) { +int redisSetBlocking(redisContext *c, int blocking) { int flags; /* Set the socket nonblocking. diff --git a/net.h b/net.h index 2f1a0bf..011f651 100644 --- a/net.h +++ b/net.h @@ -49,5 +49,5 @@ int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, const char *source_addr); int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); int redisKeepAlive(redisContext *c, int interval); - +int redisSetBlocking(redisContext *c, int blocking); #endif