Skip to content

Commit

Permalink
Reapply hiredis patches
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Aug 17, 2023
1 parent e86190a commit 8c6aed8
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 25 deletions.
4 changes: 2 additions & 2 deletions hiredis-client/ext/redis_client/hiredis/hiredis_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ static void hiredis_init_ssl(hiredis_connection_t *connection, VALUE ssl_param)
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientCannotConnectError);
}

redisSSL *redis_ssl = redisGetSSLSocket(connection->context);
redisSSL *redis_ssl = patch_redisGetSSLSocket(connection->context);

if (redis_ssl->wantRead) {
int readable = 0;
Expand All @@ -556,7 +556,7 @@ static void hiredis_init_ssl(hiredis_connection_t *connection, VALUE ssl_param)
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientReadTimeoutError);
}

if (redisInitiateSSLContinue(connection->context) != REDIS_OK) {
if (patch_redisInitiateSSLContinue(connection->context) != REDIS_OK) {
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientCannotConnectError);
};
}
Expand Down
30 changes: 30 additions & 0 deletions hiredis-client/ext/redis_client/hiredis/vendor/hiredis_ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,36 @@ struct ssl_st;
*/
typedef struct redisSSLContext redisSSLContext;


/* PATCH, see https://github.com/redis/hiredis/issues/1059 */
#include <openssl/ssl.h>
/* The SSL connection context is attached to SSL/TLS connections as a privdata. */
typedef struct redisSSL {
/**
* OpenSSL SSL object.
*/
SSL *ssl;

/**
* SSL_write() requires to be called again with the same arguments it was
* previously called with in the event of an SSL_read/SSL_write situation
*/
size_t lastLen;

/** Whether the SSL layer requires read (possibly before a write) */
int wantRead;

/**
* Whether a write was requested prior to a read. If set, the write()
* should resume whenever a read takes place, if possible
*/
int pendingWrite;
} redisSSL;

redisSSL *patch_redisGetSSLSocket(redisContext *c);
int patch_redisInitiateSSLContinue(redisContext *c);
/* END OF PATCH */

/**
* Initialization errors that redisCreateSSLContext() may return.
*/
Expand Down
63 changes: 40 additions & 23 deletions hiredis-client/ext/redis_client/hiredis/vendor/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,29 +71,6 @@ struct redisSSLContext {
char *server_name;
};

/* The SSL connection context is attached to SSL/TLS connections as a privdata. */
typedef struct redisSSL {
/**
* OpenSSL SSL object.
*/
SSL *ssl;

/**
* SSL_write() requires to be called again with the same arguments it was
* previously called with in the event of an SSL_read/SSL_write situation
*/
size_t lastLen;

/** Whether the SSL layer requires read (possibly before a write) */
int wantRead;

/**
* Whether a write was requested prior to a read. If set, the write()
* should resume whenever a read takes place, if possible
*/
int pendingWrite;
} redisSSL;

/* Forward declaration */
redisContextFuncs redisContextSSLFuncs;

Expand Down Expand Up @@ -615,3 +592,43 @@ redisContextFuncs redisContextSSLFuncs = {
.write = redisSSLWrite
};

/* PATCH, see https://github.com/redis/hiredis/issues/1059 */
redisSSL *patch_redisGetSSLSocket(redisContext *c) {
return c->privctx;
}

int patch_redisInitiateSSLContinue(redisContext *c) {
if (!c->privctx) {
__redisSetError(c, REDIS_ERR_OTHER, "redisContext is not associated");
return REDIS_ERR;
}

redisSSL *rssl = (redisSSL *)c->privctx;
ERR_clear_error();
int rv = SSL_connect(rssl->ssl);
if (rv == 1) {
c->privctx = rssl;
return REDIS_OK;
}

rv = SSL_get_error(rssl->ssl, rv);
if (((c->flags & REDIS_BLOCK) == 0) &&
(rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) {
maybeCheckWant(rssl, rv);
c->privctx = rssl;
return REDIS_OK;
}

if (c->err == 0) {
char err[512];
if (rv == SSL_ERROR_SYSCALL)
snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno));
else {
unsigned long e = ERR_peek_last_error();
snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",
ERR_reason_error_string(e));
}
__redisSetError(c, REDIS_ERR_IO, err);
}
return REDIS_ERR;
}

0 comments on commit 8c6aed8

Please sign in to comment.