summaryrefslogtreecommitdiff
path: root/hiredis.c
diff options
context:
space:
mode:
authorMark Nunberg <mnunberg@haskalah.org>2017-11-27 13:10:21 +0000
committerMark Nunberg <mnunberg@haskalah.org>2019-02-20 09:10:10 -0500
commit0c1454490669f3c95e3c8b0ac6a83582d14e30e0 (patch)
tree858e159c0f3ba74849dd9f7b4a40edd93b6791fe /hiredis.c
parent4d00404b8fb47e618474d5538e4a720ac1c95d95 (diff)
Initial SSL (sync) implementation
Diffstat (limited to 'hiredis.c')
-rw-r--r--hiredis.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/hiredis.c b/hiredis.c
index bfbf483..fae8094 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -42,6 +42,7 @@
#include "hiredis.h"
#include "net.h"
#include "sds.h"
+#include "sslio.h"
static redisReply *createReplyObject(int type);
static void *createStringObject(const redisReadTask *task, char *str, size_t len);
@@ -614,7 +615,9 @@ void redisFree(redisContext *c) {
free(c->unix_sock.path);
free(c->timeout);
free(c->saddr);
- free(c);
+ if (c->ssl) {
+ redisFreeSsl(c->ssl);
+ }
}
int redisFreeKeepFd(redisContext *c) {
@@ -760,6 +763,11 @@ redisContext *redisConnectFd(int fd) {
return c;
}
+int redisSecureConnection(redisContext *c, const char *caPath,
+ const char *certPath, const char *keyPath) {
+ return redisSslCreate(c, caPath, certPath, keyPath);
+}
+
/* Set read/write timeout on a blocking socket. */
int redisSetTimeout(redisContext *c, const struct timeval tv) {
if (c->flags & REDIS_BLOCK)
@@ -774,6 +782,24 @@ int redisEnableKeepAlive(redisContext *c) {
return REDIS_OK;
}
+static int rawRead(redisContext *c, char *buf, size_t bufcap) {
+ int nread = read(c->fd, buf, bufcap);
+ if (nread == -1) {
+ if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
+ /* Try again later */
+ return 0;
+ } else {
+ __redisSetError(c, REDIS_ERR_IO, NULL);
+ return -1;
+ }
+ } else if (nread == 0) {
+ __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection");
+ return -1;
+ } else {
+ return nread;
+ }
+}
+
/* Use this function to handle a read event on the descriptor. It will try
* and read some bytes from the socket and feed them to the reply parser.
*
@@ -787,26 +813,33 @@ int redisBufferRead(redisContext *c) {
if (c->err)
return REDIS_ERR;
- nread = read(c->fd,buf,sizeof(buf));
- if (nread == -1) {
- if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
- /* Try again later */
- } else {
- __redisSetError(c,REDIS_ERR_IO,NULL);
+ nread = c->flags & REDIS_SSL ?
+ redisSslRead(c, buf, sizeof(buf)) : rawRead(c, buf, sizeof(buf));
+ if (nread > 0) {
+ if (redisReaderFeed(c->reader, buf, nread) != REDIS_OK) {
+ __redisSetError(c, c->reader->err, c->reader->errstr);
return REDIS_ERR;
+ } else {
}
- } else if (nread == 0) {
- __redisSetError(c,REDIS_ERR_EOF,"Server closed the connection");
+ } else if (nread < 0) {
return REDIS_ERR;
- } else {
- if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
- __redisSetError(c,c->reader->err,c->reader->errstr);
- return REDIS_ERR;
- }
}
return REDIS_OK;
}
+static int rawWrite(redisContext *c) {
+ int nwritten = write(c->fd, c->obuf, sdslen(c->obuf));
+ if (nwritten < 0) {
+ if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
+ /* Try again later */
+ } else {
+ __redisSetError(c, REDIS_ERR_IO, NULL);
+ return -1;
+ }
+ }
+ return nwritten;
+}
+
/* Write the output buffer to the socket.
*
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
@@ -817,21 +850,15 @@ int redisBufferRead(redisContext *c) {
* c->errstr to hold the appropriate error string.
*/
int redisBufferWrite(redisContext *c, int *done) {
- int nwritten;
/* Return early when the context has seen an error. */
if (c->err)
return REDIS_ERR;
if (sdslen(c->obuf) > 0) {
- nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
- if (nwritten == -1) {
- if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
- /* Try again later */
- } else {
- __redisSetError(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
+ int nwritten = (c->flags & REDIS_SSL) ? redisSslWrite(c) : rawWrite(c);
+ if (nwritten < 0) {
+ return REDIS_ERR;
} else if (nwritten > 0) {
if (nwritten == (signed)sdslen(c->obuf)) {
sdsfree(c->obuf);