summaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
authorMark Nunberg <mnunberg@haskalah.org>2018-03-04 18:17:16 +0200
committerMark Nunberg <mnunberg@haskalah.org>2018-09-25 20:21:37 -0400
commit49974c9359ad6b58cea15106cf6511bdb31d31a9 (patch)
tree5cfbe5664581f331404fde52c5b169d5af2397dc /net.c
parent685030652cd98c5414ce554ff5b356dfe8437870 (diff)
Call connect(2) again for non-blocking connect
This retrieves the actual error which occurred, as getsockopt is not always reliable in this regard.
Diffstat (limited to 'net.c')
-rw-r--r--net.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/net.c b/net.c
index 5d50f7c..62c6ca0 100644
--- a/net.c
+++ b/net.c
@@ -232,8 +232,28 @@ static int redisContextWaitReady(redisContext *c, long msec) {
return REDIS_ERR;
}
+int redisFinishAsyncConnect(redisContext *c, int *completed) {
+ int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen);
+ if (rc == 0) {
+ *completed = 1;
+ return REDIS_OK;
+ }
+ switch (errno) {
+ case EISCONN:
+ *completed = 1;
+ return REDIS_OK;
+ case EALREADY:
+ case EINPROGRESS:
+ case EWOULDBLOCK:
+ *completed = 0;
+ return REDIS_OK;
+ default:
+ return REDIS_ERR;
+ }
+}
+
int redisCheckSocketError(redisContext *c) {
- int err = 0;
+ int err = 0, errno_saved = errno;
socklen_t errlen = sizeof(err);
if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
@@ -241,6 +261,10 @@ int redisCheckSocketError(redisContext *c) {
return REDIS_ERR;
}
+ if (err == 0) {
+ err = errno_saved;
+ }
+
if (err) {
errno = err;
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
@@ -373,6 +397,15 @@ addrretry:
goto error;
}
}
+
+ /* For repeat connection */
+ if (c->saddr) {
+ free(c->saddr);
+ }
+ c->saddr = malloc(sizeof(*p->ai_addr));
+ memcpy(c->saddr, p->ai_addr, p->ai_addrlen);
+ c->addrlen = p->ai_addrlen;
+
if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
if (errno == EHOSTUNREACH) {
redisContextCloseFd(c);