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

fix memleak #92

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions .gitignore
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
/*.dylib
/*.a
/*.pc
testcases/testcase-cluster
testcases/testcase-redis
Empty file modified .travis.yml
100644 → 100755
Empty file.
Empty file modified CHANGELOG.md
100644 → 100755
Empty file.
Empty file modified COPYING
100644 → 100755
Empty file.
7 changes: 7 additions & 0 deletions Makefile
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-
TESTS=hiredis-test
LIBNAME=libhiredis_vip
PKGCONFNAME=hiredis_vip.pc
TESTCASES=testcase-cluster

HIREDIS_VIP_MAJOR=$(shell grep HIREDIS_VIP_MAJOR hircluster.h | awk '{print $$3}')
HIREDIS_VIP_MINOR=$(shell grep HIREDIS_VIP_MINOR hircluster.h | awk '{print $$3}')
Expand Down Expand Up @@ -125,6 +126,12 @@ hiredis-example: examples/example.c $(STLIBNAME)

examples: $(EXAMPLES)

testcase-cluster: testcases/cluster.c $(STLIBNAME)
$(CC) -o testcases/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)

testcase-redis: testcases/redis.c $(STLIBNAME)
$(CC) -o testcases/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)

hiredis-test: test.o $(STLIBNAME)

hiredis-%: %.o $(STLIBNAME)
Expand Down
8 changes: 8 additions & 0 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void redisClusterFree(redisClusterContext *cc);

int redisClusterSetOptionAddNode(redisClusterContext *cc, const char *addr);
int redisClusterSetOptionAddNodes(redisClusterContext *cc, const char *addrs);
int redisClusterSetOptionSetAuth(redisClusterContext *cc, const char *auth);
int redisClusterSetOptionConnectBlock(redisClusterContext *cc);
int redisClusterSetOptionConnectNonBlock(redisClusterContext *cc);
int redisClusterSetOptionParseSlaves(redisClusterContext *cc);
Expand Down Expand Up @@ -73,8 +74,11 @@ redisAsyncContext *actx_get_by_node(redisClusterAsyncContext *acc, cluster_node

```c
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 *redisClusterConnectWithTimeoutWithAuth(const char *addrs, const char *auth, const struct timeval tv, int flags);
redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags);
redisClusterContext *redisClusterConnectNonBlockWithAuth(const char *addrs, const char *auth, int flags);
void redisClusterFree(redisClusterContext *cc);
void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count);
void *redisClusterFormattedCommand(redisClusterContext *cc, char *cmd, int len);
Expand All @@ -90,6 +94,7 @@ int redisClusterGetReply(redisClusterContext *cc, void **reply);
void redisClusterReset(redisClusterContext *cc);

redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags);
redisClusterAsyncContext *redisClusterAsyncConnectWithAuth(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);
Expand All @@ -113,6 +118,7 @@ To consume the synchronous API, there are only a few function calls that need to
```c
redisClusterContext *redisClusterContextInit(void);
int redisClusterSetOptionAddNodes(redisClusterContext *cc, const char *addrs);
int redisClusterSetOptionSetAuth(redisClusterContext *cc, const char *auth);
int redisClusterSetOptionMaxRedirect(redisClusterContext *cc, int max_redirect_count);
int redisClusterSetOptionConnectTimeout(redisClusterContext *cc, const struct timeval tv);
int redisClusterSetOptionTimeout(redisClusterContext *cc, const struct timeval tv);
Expand All @@ -125,6 +131,7 @@ void redisClusterFree(redisClusterContext *cc);

The function `redisClusterContextInit` is used to create a so-called `redisClusterContext`.
The function `redisClusterSetOptionAddNodes` is used to add the redis cluster address.
The function `redisClusterSetOptionSetAuth` is used to add the redis cluster password.
The function `redisClusterConnect2` is used to connect to the redis cluser.
The context is where Hiredis-vip Cluster holds state for connections. The `redisClusterContext`
struct has an integer `err` field that is non-zero when the connection is in
Expand All @@ -135,6 +142,7 @@ check the `err` field to see if establishing the connection was successful:
```c
redisClusterContext *cc = redisClusterContextInit();
redisClusterSetOptionAddNodes(cc, "127.0.0.1:6379,127.0.0.1:6380");
redisClusterSetOptionSetAuth(cc, "P@ssw0rd");
redisClusterConnect2(cc);
if (cc != NULL && cc->err) {
printf("Error: %s\n", cc->errstr);
Expand Down
Empty file modified adapters/ae.h
100644 → 100755
Empty file.
Empty file modified adapters/glib.h
100644 → 100755
Empty file.
Empty file modified adapters/libev.h
100644 → 100755
Empty file.
Empty file modified adapters/libevent.h
100644 → 100755
Empty file.
Empty file modified adapters/libuv.h
100644 → 100755
Empty file.
Empty file modified adlist.c
100644 → 100755
Empty file.
Empty file modified adlist.h
100644 → 100755
Empty file.
Empty file modified async.c
100644 → 100755
Empty file.
Empty file modified async.h
100644 → 100755
Empty file.
Empty file modified command.c
100644 → 100755
Empty file.
Empty file modified command.h
100644 → 100755
Empty file.
Empty file modified crc16.c
100644 → 100755
Empty file.
Empty file modified dict.c
100644 → 100755
Empty file.
Empty file modified dict.h
100644 → 100755
Empty file.
Empty file modified examples/example-ae.c
100644 → 100755
Empty file.
Empty file modified examples/example-glib.c
100644 → 100755
Empty file.
Empty file modified examples/example-libev.c
100644 → 100755
Empty file.
Empty file modified examples/example-libevent.c
100644 → 100755
Empty file.
Empty file modified examples/example-libuv.c
100644 → 100755
Empty file.
Empty file modified examples/example.c
100644 → 100755
Empty file.
Empty file modified fmacros.h
100644 → 100755
Empty file.
Empty file modified hiarray.c
100644 → 100755
Empty file.
Empty file modified hiarray.h
100644 → 100755
Empty file.
174 changes: 160 additions & 14 deletions hircluster.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -338,6 +339,21 @@ static void cluster_node_deinit(cluster_node *node)
}
}


static int auth_after_connect (redisClusterContext *cc, redisContext *c)
{
if(cc->auth){
redisReply *reply ;
reply = redisCommand(c, "auth %s", cc->auth);
if(reply == NULL){
__redisClusterSetError(cc,REDIS_ERR_OTHER, "Command(auth XXXXX) reply error(NULL).");
return 1;
}
freeReplyObject(reply);
}
return 0;
}

static int cluster_slot_init(cluster_slot *slot, cluster_node *node)
{
slot->start = 0;
Expand Down Expand Up @@ -1294,6 +1310,10 @@ cluster_update_route_by_addr(redisClusterContext *cc,
goto error;
}

if (auth_after_connect (cc, c) == 1) {
goto error;
}

if (cc->timeout) {
redisSetTimeout(c, *cc->timeout);
}
Expand Down Expand Up @@ -1547,6 +1567,10 @@ cluster_update_route_with_nodes_old(redisClusterContext *cc,
goto error;
}

if (auth_after_connect (cc, c) == 1) {
goto error;
}

reply = redisCommand(c, REDIS_COMMAND_CLUSTER_NODES);

if(reply == NULL)
Expand Down Expand Up @@ -1950,7 +1974,7 @@ cluster_update_route(redisClusterContext *cc)
return REDIS_ERR;
}

static void print_cluster_node_list(redisClusterContext *cc)
void print_cluster_node_list(redisClusterContext *cc)
{
dictIterator *di = NULL;
dictEntry *de;
Expand Down Expand Up @@ -1994,18 +2018,6 @@ static void print_cluster_node_list(redisClusterContext *cc)
}
}


int test_cluster_update_route(redisClusterContext *cc)
{
int ret;

ret = cluster_update_route(cc);

//print_cluster_node_list(cc);

return ret;
}

redisClusterContext *redisClusterContextInit(void) {
redisClusterContext *cc;

Expand All @@ -2015,6 +2027,7 @@ redisClusterContext *redisClusterContextInit(void) {

cc->err = 0;
cc->errstr[0] = '\0';
cc->auth[0] = '\0';
cc->ip = NULL;
cc->port = 0;
cc->flags = 0;
Expand Down Expand Up @@ -2133,6 +2146,26 @@ redisClusterContext *redisClusterConnect(const char *addrs, int 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)
{
Expand Down Expand Up @@ -2161,6 +2194,38 @@ redisClusterContext *redisClusterConnectWithTimeout(
return _redisClusterConnect(cc, addrs);
}

redisClusterContext *redisClusterConnectWithTimeoutWithAuth(const char *addrs, const char *auth, const struct timeval tv, int flags)
{
redisClusterContext *cc;

cc = redisClusterContextInit();

if(cc == NULL)
{
return NULL;
}

cc->flags |= REDIS_BLOCK;
if(flags)
{
cc->flags |= flags;
}

if (cc->connect_timeout == NULL)
{
cc->connect_timeout = malloc(sizeof(struct timeval));
}

memcpy(cc->connect_timeout, &tv, sizeof(struct timeval));

if(auth)
{
memcpy(cc->auth, auth, strlen(auth));
}

return _redisClusterConnect(cc, addrs);
}

redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags) {

redisClusterContext *cc;
Expand All @@ -2181,6 +2246,31 @@ redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags) {
return _redisClusterConnect(cc, addrs);
}

redisClusterContext *redisClusterConnectNonBlockWithAuth(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);
}

int redisClusterSetOptionAddNode(redisClusterContext *cc, const char *addr)
{
dictEntry *node_entry;
Expand Down Expand Up @@ -2265,6 +2355,18 @@ int redisClusterSetOptionAddNode(redisClusterContext *cc, const char *addr)
return REDIS_OK;
}


int redisClusterSetOptionSetAuth(redisClusterContext *cc, const char *auth)
{
if(cc == NULL) {
return REDIS_ERR;
}
if(auth) {
memcpy(cc->auth, auth, strlen(auth));
}
return 0;
}

int redisClusterSetOptionAddNodes(redisClusterContext *cc, const char *addrs)
{
int ret;
Expand Down Expand Up @@ -2503,6 +2605,11 @@ redisContext *ctx_get_by_node(redisClusterContext *cc, cluster_node *node)
c = redisConnect(node->host, node->port);
}

if (auth_after_connect (cc, c) == 1) {
redisFree(c);
c = NULL;
}

if (cc->timeout && c != NULL && c->err == 0) {
redisSetTimeout(c, *cc->timeout);
}
Expand Down Expand Up @@ -3436,23 +3543,27 @@ static void *command_post_fragment(redisClusterContext *cc,
reply = sub_command->reply;
if(reply == NULL)
{
listReleaseIterator(list_iter);
return NULL;
}
else if(reply->type == REDIS_REPLY_ERROR)
{
listReleaseIterator(list_iter);
return reply;
}

if (command->type == CMD_REQ_REDIS_MGET) {
if(reply->type != REDIS_REPLY_ARRAY)
{
__redisClusterSetError(cc,REDIS_ERR_OTHER,"reply type is error(here only can be array)");
listReleaseIterator(list_iter);
return NULL;
}
}else if(command->type == CMD_REQ_REDIS_DEL){
if(reply->type != REDIS_REPLY_INTEGER)
{
__redisClusterSetError(cc,REDIS_ERR_OTHER,"reply type is error(here only can be integer)");
listReleaseIterator(list_iter);
return NULL;
}

Expand All @@ -3462,12 +3573,14 @@ static void *command_post_fragment(redisClusterContext *cc,
reply->len != 2 || strcmp(reply->str, REDIS_STATUS_OK) != 0)
{
__redisClusterSetError(cc,REDIS_ERR_OTHER,"reply type is error(here only can be status and ok)");
listReleaseIterator(list_iter);
return NULL;
}
}else {
NOT_REACHED();
}
}
listReleaseIterator(list_iter);

reply = hi_calloc(1,sizeof(*reply));

Expand Down Expand Up @@ -4365,8 +4478,19 @@ redisAsyncContext * actx_get_by_node(redisClusterAsyncContext *acc,

ac->data = node;
ac->dataHandler = unlinkAsyncContextAndNode;

if (acc->cc->auth) {
ac->c.flags |= REDIS_BLOCK;
redisSetBlocking(&ac->c, 1);
if (auth_after_connect (acc->cc, &ac->c) == 1) {
redisAsyncFree(ac);
ac = NULL;
return ac;
}
redisSetBlocking(&ac->c, 0);
ac->c.flags &= ~REDIS_BLOCK;
}
node->acon = ac;

return ac;
}

Expand Down Expand Up @@ -4443,6 +4567,28 @@ redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags)
return acc;
}

redisClusterAsyncContext *redisClusterAsyncConnectWithAuth(const char *addrs, const char *auth, int flags) {

redisClusterContext *cc;
redisClusterAsyncContext *acc;

cc = redisClusterConnectNonBlockWithAuth(addrs, auth, flags);
if(cc == NULL)
{
return NULL;
}

acc = redisClusterAsyncInitialize(cc);
if (acc == NULL) {
redisClusterFree(cc);
return NULL;
}

__redisClusterAsyncCopyError(acc);

return acc;
}


int redisClusterAsyncSetConnectCallback(
redisClusterAsyncContext *acc, redisConnectCallback *fn)
Expand Down
Loading