From c5994f2a42b8a348af92d3acb4edff1328ad8ce1 Mon Sep 17 00:00:00 2001 From: Pavlo Yatsukhnenko Date: Tue, 15 Jan 2019 10:07:30 +0200 Subject: RedisCluster auth --- cluster_library.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'cluster_library.c') diff --git a/cluster_library.c b/cluster_library.c index 1f6d4160..b0f7b53a 100644 --- a/cluster_library.c +++ b/cluster_library.c @@ -259,6 +259,17 @@ cluster_read_sock_resp(RedisSock *redis_sock, REDIS_REPLY_TYPE type, return r; } +/* Helper to open connection and send AUTH if necessary */ +static zend_always_inline int +cluster_sock_open(RedisSock *redis_sock TSRMLS_DC) +{ + zend_bool need_auth = (redis_sock->auth && redis_sock->status != REDIS_SOCK_STATUS_CONNECTED); + if (!redis_sock_server_open(redis_sock TSRMLS_CC) && (!need_auth || !redis_sock_auth(redis_sock TSRMLS_CC))) { + return SUCCESS; + } + return FAILURE; +} + /* * Helpers to send various 'control type commands to a specific node, e.g. * MULTI, ASKING, READONLY, READWRITE, etc @@ -654,6 +665,10 @@ cluster_node_create(redisCluster *c, char *host, size_t host_len, node->sock = redis_sock_create(host, host_len, port, c->timeout, c->read_timeout, c->persistent, NULL, 0); + if (c->auth) { + node->sock->auth = zend_string_copy(c->auth); + } + return node; } @@ -824,6 +839,7 @@ PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout, c->read_timeout = read_timeout; c->failover = failover; c->persistent = persistent; + c->auth = NULL; c->err = NULL; /* Set up our waitms based on timeout */ @@ -858,6 +874,9 @@ cluster_free(redisCluster *c, int free_ctx TSRMLS_DC) efree(c->seeds); efree(c->nodes); + /* Free auth info we've got */ + if (c->auth) zend_string_release(c->auth); + /* Free any error we've got */ if (c->err) zend_string_release(c->err); @@ -925,6 +944,11 @@ cluster_init_seeds(redisCluster *cluster, HashTable *ht_seeds) { (unsigned short)atoi(psep+1), cluster->timeout, cluster->read_timeout, cluster->persistent, NULL, 0); + // Set auth information if specified + if (cluster->auth) { + redis_sock->auth = zend_string_copy(cluster->auth); + } + // Index this seed by host/port key_len = snprintf(key, sizeof(key), "%s:%u", ZSTR_VAL(redis_sock->host), redis_sock->port); @@ -948,7 +972,7 @@ PHP_REDIS_API int cluster_map_keyspace(redisCluster *c TSRMLS_DC) { // Iterate over seeds until we can get slots ZEND_HASH_FOREACH_PTR(c->seeds, seed) { // Attempt to connect to this seed node - if (seed == NULL || redis_sock_connect(seed TSRMLS_CC) != 0) { + if (seed == NULL || cluster_sock_open(seed TSRMLS_CC) != 0) { continue; } @@ -1119,11 +1143,6 @@ static int cluster_dist_write(redisCluster *c, const char *cmd, size_t sz, redis_sock = cluster_slot_sock(c, c->cmd_slot, nodes[i]); if (!redis_sock) continue; - /* Connect to this node if we haven't already */ - if(redis_sock_server_open(redis_sock TSRMLS_CC)) { - continue; - } - /* If we're not on the master, attempt to send the READONLY command to * this slave, and skip it if that fails */ if (nodes[i] == 0 || redis_sock->readonly || -- cgit v1.2.3