Commit 1bcf4024 authored by michael-grunder's avatar michael-grunder
Browse files

Add a user-defined callback to set custom socket options.

Fixes #698
parent 855b48a8
......@@ -829,6 +829,9 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
c->flags |= REDIS_PREFER_IPV6;
}
/* Set any configured socket callback function */
c->socket_cb = options->socket_cb;
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
* as a default unless specifically flagged that we don't want one. */
if (options->push_cb != NULL)
......
......@@ -216,6 +216,10 @@ typedef struct {
redisFD fd;
} endpoint;
/* Socket callback function executed after socket creation but before
* we connect. This can be used to set OS specific socket options. */
int (*socket_cb)(redisFD fd, void *privdata, char **errstr);
/* Optional user defined data/destructor */
void *privdata;
void (*free_privdata)(void *);
......@@ -239,6 +243,10 @@ typedef struct {
(opts)->endpoint.unix_socket = path; \
} while(0)
#define REDIS_OPTIONS_SET_SOCKET_CB(opts, cb) do { \
(opts)->socket_cb = cb; \
} while(0)
#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) do { \
(opts)->privdata = data; \
(opts)->free_privdata = dtor; \
......@@ -288,6 +296,11 @@ typedef struct redisContext {
struct sockaddr *saddr;
size_t addrlen;
/* A callback to be invoked after successful socket creation but before we
* connect. This can be usefull for setting OS specific socket flags.
* The callback may optionally set errstr in the event of an error. */
int (*socket_cb)(redisFD fd, void *privdata, char **errstr);
/* Optional data and corresponding destructor users can use to provide
* context to a given redisContext. Not used by hiredis. */
void *privdata;
......
......@@ -402,6 +402,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
int rv, n;
char _port[6]; /* strlen("65535"); */
struct addrinfo hints, *servinfo, *bservinfo, *p, *b;
char *errstr;
int blocking = (c->flags & REDIS_BLOCK);
int reuseaddr = (c->flags & REDIS_REUSEADDR);
int reuses = 0;
......@@ -477,6 +478,13 @@ addrretry:
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD)
continue;
/* Invoke any user-provided socket callback */
errstr = NULL;
if (c->socket_cb && c->socket_cb(s, c->privdata, &errstr) != REDIS_OK) {
__redisSetError(c, REDIS_ERR_OTHER, errstr ? errstr : "Failure in user-defined socket callback");
goto error;
}
c->fd = s;
if (redisSetBlocking(c,0) != REDIS_OK)
goto error;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment