Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: redisContextConnectUnix has bug. #1260

Closed
CodeIsPower1 opened this issue May 27, 2024 · 0 comments · Fixed by #1262
Closed

API: redisContextConnectUnix has bug. #1260

CodeIsPower1 opened this issue May 27, 2024 · 0 comments · Fixed by #1262

Comments

@CodeIsPower1
Copy link

V1.2.0
`
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
#ifndef _WIN32
int blocking = (c->flags & REDIS_BLOCK);
struct sockaddr_un *sa;
long timeout_msec = -1;

if (redisCreateSocket(c,AF_UNIX) < 0)
    return REDIS_ERR;
if (redisSetBlocking(c,0) != REDIS_OK)
    return REDIS_ERR;

c->connection_type = REDIS_CONN_UNIX;
if (c->unix_sock.path != path) {
    hi_free(c->unix_sock.path);

    c->unix_sock.path = hi_strdup(path);
    if (c->unix_sock.path == NULL)
        goto oom;
}

if (timeout) {
    if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR)
        goto oom;
} else {
    hi_free(c->connect_timeout);
    c->connect_timeout = NULL;
}

if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
    return REDIS_ERR;

/* Don't leak sockaddr if we're reconnecting */
if (c->saddr) hi_free(c->saddr);

sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un)));
if (sa == NULL)
    goto oom;

c->addrlen = sizeof(struct sockaddr_un);
sa->sun_family = AF_UNIX;
strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) {
    if (errno == EINPROGRESS && !blocking) {
        /* This is ok. */
    } else {
        if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
            return REDIS_ERR;
    }
}

/* Reset socket to be blocking after connect(2). */
if (blocking && redisSetBlocking(c,1) != REDIS_OK)
    return REDIS_ERR;

c->flags |= REDIS_CONNECTED;
return REDIS_OK;

#else
/* We currently do not support Unix sockets for Windows. /
/
TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ /
errno = EPROTONOSUPPORT;
return REDIS_ERR;
#endif /
_WIN32 */
oom:
__redisSetError(c, REDIS_ERR_OOM, "Out of memory");
return REDIS_ERR;
}
`

///////////////////////////////////////////(man connect )///////////////////////////////////////////////////////////
EAGAIN For nonblocking UNIX domain sockets, the socket is nonblocking,
and the connection cannot be completed immediately. For other
socket families, there are insufficient entries in the routing
cache.

   EALREADY
          The socket is nonblocking and a previous connection attempt  has
          not yet been completed.

   EBADF  sockfd is not a valid open file descriptor.

   ECONNREFUSED
          A connect() on a stream socket found no one listening on the re‐
          mote address.

   EFAULT The socket structure  address  is  outside  the  user's  address
          space.

   EINPROGRESS
          The socket is nonblocking and the connection cannot be completed
          immediately.  (UNIX domain sockets failed with EAGAIN  instead.)
          It is possible to select(2) or poll(2) for completion by select‐
          ing the socket for writing.  After select(2) indicates writabil‐
          ity,  use  getsockopt(2)  to  read  the SO_ERROR option at level
          SOL_SOCKET to determine whether connect() completed successfully
          (SO_ERROR  is  zero)  or  unsuccessfully (SO_ERROR is one of the
          usual error codes listed here, explaining  the  reason  for  the
          failure).

///////////////////////////////////////////////////(conclusion)///////////////////////////////////////////////////////////////////
For unix socket ,connect with non-blocking will return EAGAIN,not EINPROGRESS

michael-grunder added a commit that referenced this issue May 27, 2024
Reading the manpage it seems like we only need to test for `EAGAIN` but
testing for both seems more prudent since this may be subtly different
on more esoteric kernels (SunOS, AIX, BSD, etc).

Fixes #1260
michael-grunder added a commit to michael-grunder/hiredis that referenced this issue May 28, 2024
Reading the manpage it seems like we only need to test for `EAGAIN` but
testing for both seems more prudent since this may be subtly different
on more esoteric kernels (SunOS, AIX, BSD, etc).

Also explicitly install openSSL3 on macOS.

Fixes redis#1260
michael-grunder added a commit that referenced this issue Aug 20, 2024
Reading the manpage it seems like we only need to test for `EAGAIN` but
testing for both seems more prudent since this may be subtly different
on more esoteric kernels (SunOS, AIX, BSD, etc).

Fixes #1260
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant