int redisContextPreConnectTcp( redisContext *c, const char *addr, int port, struct timeval *timeout, SOCKADDR_STORAGE* ss) { int blocking = (c->flags & REDIS_BLOCK); if (ParseStorageAddress(addr, port, ss) == FALSE) { DebugBreak(); } if (REDIS_OK != redisCreateSocket(c, ss->ss_family)) { return REDIS_ERR; } if (redisSetTcpNoDelay(c) != REDIS_OK) return REDIS_ERR; if (blocking == 0) { if (redisSetBlocking(c, 0) != REDIS_OK) return REDIS_ERR; } return REDIS_OK; }
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout) { int s, rv; char _port[6]; /* strlen("65535"); */ struct addrinfo hints, *servinfo, *p; int blocking = (c->flags & REDIS_BLOCK); snprintf(_port, 6, "%d", port); memset(&hints,0,sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); return REDIS_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; if (redisSetBlocking(c,s,0) != REDIS_OK) goto error; if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { SETERRNO; if (errno == EHOSTUNREACH) { close(s); continue; } else if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { if (redisContextWaitReady(c,s,timeout) != REDIS_OK) goto error; } } if (blocking && redisSetBlocking(c,s,1) != REDIS_OK) goto error; if (redisSetTcpNoDelay(c,s) != REDIS_OK) goto error; c->fd = s; c->flags |= REDIS_CONNECTED; rv = REDIS_OK; goto end; } if (p == NULL) { char buf[128]; snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } error: rv = REDIS_ERR; end: freeaddrinfo(servinfo); return rv; // Need to return REDIS_OK if alright }
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout) { int s; int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_in sa; if ((s = redisCreateSocket(c,AF_INET)) < 0) return REDIS_ERR; if (redisSetBlocking(c,s,0) != REDIS_OK) return REDIS_ERR; sa.sin_family = AF_INET; sa.sin_port = htons(port); if (inet_aton(addr, &sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { __redisSetError(c,REDIS_ERR_OTHER, sdscatprintf(sdsempty(),"Can't resolve: %s",addr)); close(s); return REDIS_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { if (redisContextWaitReady(c,s,timeout) != REDIS_OK) return REDIS_ERR; } } /* Reset socket to be blocking after connect(2). */ if (blocking && redisSetBlocking(c,s,1) != REDIS_OK) return REDIS_ERR; if (redisSetTcpNoDelay(c,s) != REDIS_OK) return REDIS_ERR; #ifdef ALCHEMY_DATABASE DXDB_setSA(sa); #endif c->fd = s; c->flags |= REDIS_CONNECTED; return REDIS_OK; }
int redisContextConnectTcp(redisContext *c, const char *addr, int port) { int s; int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_in sa; if ((s = redisCreateSocket(c,AF_INET)) == REDIS_ERR) return REDIS_ERR; if (!blocking && redisSetNonBlock(c,s) == REDIS_ERR) return REDIS_ERR; sa.sin_family = AF_INET; sa.sin_port = htons(port); if (inet_aton(addr, &sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { __redisSetError(c,REDIS_ERR_OTHER, sdscatprintf(sdsempty(),"Can't resolve: %s",addr)); closesocket(c->fd); WSACleanup(); return REDIS_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (WSAGetLastError() == WSAEINPROGRESS && !blocking) { /* This is ok. */ } else { __redisSetError(c,REDIS_ERR_IO,NULL); closesocket(c->fd); WSACleanup(); return REDIS_ERR; } } if (redisSetTcpNoDelay(c,s) != REDIS_OK) { closesocket(c->fd); WSACleanup(); return REDIS_ERR; } c->fd = s; c->flags |= REDIS_CONNECTED; return REDIS_OK; }
static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout, const char *source_addr) { int s, rv, n; char _port[6]; /* strlen("65535"); */ struct addrinfo hints, *servinfo, *bservinfo, *p, *b; int blocking = (c->flags & REDIS_BLOCK); int reuseaddr = (c->flags & REDIS_REUSEADDR); int reuses = 0; long timeout_msec = -1; servinfo = NULL; c->connection_type = REDIS_CONN_TCP; c->tcp.port = port; /* We need to take possession of the passed parameters * to make them reusable for a reconnect. * We also carefully check we don't free data we already own, * as in the case of the reconnect method. * * This is a bit ugly, but atleast it works and doesn't leak memory. **/ if (c->tcp.host != addr) { if (c->tcp.host) free(c->tcp.host); c->tcp.host = strdup(addr); } if (timeout) { if (c->timeout != timeout) { if (c->timeout == NULL) c->timeout = malloc(sizeof(struct timeval)); memcpy(c->timeout, timeout, sizeof(struct timeval)); } } else { if (c->timeout) free(c->timeout); c->timeout = NULL; } if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); goto error; } if (source_addr == NULL) { free(c->tcp.source_addr); c->tcp.source_addr = NULL; } else if (c->tcp.source_addr != source_addr) { free(c->tcp.source_addr); c->tcp.source_addr = strdup(source_addr); } snprintf(_port, 6, "%d", port); memset(&hints,0,sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; /* Try with IPv6 if no IPv4 address was found. We do it in this order since * in a Redis client you can't afford to test if you have IPv6 connectivity * as this would add latency to every connect. Otherwise a more sensible * route could be: Use IPv6 if both addresses are available and there is IPv6 * connectivity. */ if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) { hints.ai_family = AF_INET6; if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); return REDIS_ERR; } } for (p = servinfo; p != NULL; p = p->ai_next) { addrretry: if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; c->fd = s; if (redisSetBlocking(c,0) != REDIS_OK) goto error; if (c->tcp.source_addr) { int bound = 0; /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) { char buf[128]; snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } if (reuseaddr) { n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, sizeof(n)) < 0) { goto error; } } for (b = bservinfo; b != NULL; b = b->ai_next) { if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { bound = 1; break; } } freeaddrinfo(bservinfo); if (!bound) { char buf[128]; snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } } if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EHOSTUNREACH) { redisContextCloseFd(c); continue; } else if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else if (errno == EADDRNOTAVAIL && reuseaddr) { if (++reuses >= REDIS_CONNECT_RETRIES) { goto error; } else { goto addrretry; } } else { if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) goto error; } } if (blocking && redisSetBlocking(c,1) != REDIS_OK) goto error; if (redisSetTcpNoDelay(c) != REDIS_OK) goto error; c->flags |= REDIS_CONNECTED; rv = REDIS_OK; goto end; } if (p == NULL) { char buf[128]; snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } error: rv = REDIS_ERR; end: freeaddrinfo(servinfo); return rv; // Need to return REDIS_OK if alright }
static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout, const char *source_addr) { #ifdef FASTOREDIS if(c->session){ if (!(c->channel = libssh2_channel_direct_tcpip(c->session, addr, port))) { __redisSetError(c, REDIS_ERR_OTHER, "Unable to open a ssh session"); return REDIS_ERR; } c->flags |= REDIS_CONNECTED; return REDIS_OK; } #endif int s, rv, n; char _port[6]; /* strlen("65535"); */ struct addrinfo hints, *servinfo, *bservinfo, *p, *b; int blocking = (c->flags & REDIS_BLOCK); int reuseaddr = (c->flags & REDIS_REUSEADDR); int reuses = 0; snprintf(_port, 6, "%d", port); memset(&hints,0,sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; /* Try with IPv6 if no IPv4 address was found. We do it in this order since * in a Redis client you can't afford to test if you have IPv6 connectivity * as this would add latency to every connect. Otherwise a more sensible * route could be: Use IPv6 if both addresses are available and there is IPv6 * connectivity. */ if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { hints.ai_family = AF_INET6; if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); return REDIS_ERR; } } for (p = servinfo; p != NULL; p = p->ai_next) { addrretry: if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; c->fd = s; if (redisSetBlocking(c,0) != REDIS_OK) goto error; if (source_addr) { int bound = 0; /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0) { char buf[128]; snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } if (reuseaddr) { n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, sizeof(n)) < 0) { goto error; } } for (b = bservinfo; b != NULL; b = b->ai_next) { if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { bound = 1; break; } } freeaddrinfo(bservinfo); if (!bound) { char buf[128]; snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } } if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EHOSTUNREACH) { redisContextCloseFd(c); continue; } else if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else if (errno == EADDRNOTAVAIL && reuseaddr) { if (++reuses >= REDIS_CONNECT_RETRIES) { goto error; } else { goto addrretry; } } else { if (redisContextWaitReady(c,timeout) != REDIS_OK) goto error; } } if (blocking && redisSetBlocking(c,1) != REDIS_OK) goto error; if (redisSetTcpNoDelay(c) != REDIS_OK) goto error; c->flags |= REDIS_CONNECTED; rv = REDIS_OK; goto end; } if (p == NULL) { char buf[128]; snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } error: rv = REDIS_ERR; end: freeaddrinfo(servinfo); return rv; // Need to return REDIS_OK if alright }
int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout) { int s, rv; char _port[6]; /* strlen("65535"); */ struct addrinfo hints, *servinfo, *p; int blocking = (c->flags & REDIS_BLOCK); snprintf(_port, 6, "%d", port); memset(&hints,0,sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; /* Try with IPv6 if no IPv4 address was found. We do it in this order since * in a Redis client you can't afford to test if you have IPv6 connectivity * as this would add latency to every connect. Otherwise a more sensible * route could be: Use IPv6 if both addresses are available and there is IPv6 * connectivity. */ if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { hints.ai_family = AF_INET6; if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); return REDIS_ERR; } } for (p = servinfo; p != NULL; p = p->ai_next) { if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; if (redisSetBlocking(c,s,0) != REDIS_OK) goto error; if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EHOSTUNREACH) { close(s); continue; } else if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { if (redisContextWaitReady(c,s,timeout) != REDIS_OK) goto error; } } if (blocking && redisSetBlocking(c,s,1) != REDIS_OK) goto error; if (redisSetTcpNoDelay(c,s) != REDIS_OK) goto error; c->fd = s; c->flags |= REDIS_CONNECTED; rv = REDIS_OK; goto end; } if (p == NULL) { char buf[128]; snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); goto error; } error: rv = REDIS_ERR; end: freeaddrinfo(servinfo); return rv; // Need to return REDIS_OK if alright }
int redisContextConnectTcp(redisContext *c, const char *addr, int port) { int s; int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_in sa; if ((s = redisCreateSocket(c,AF_INET)) == REDIS_ERR) return REDIS_ERR; if (!blocking && redisSetNonBlock(c,s) == REDIS_ERR) return REDIS_ERR; sa.sin_family = AF_INET; sa.sin_port = htons(port); #ifdef _WIN32 unsigned long inAddress; inAddress = inet_addr(addr); if (inAddress == INADDR_NONE || inAddress == INADDR_ANY) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { __redisSetError(c,REDIS_ERR_OTHER, sdscatprintf(sdsempty(),"can't resolve: %s\n", addr)); closesocket(s); return REDIS_ERR;; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } else { sa.sin_addr.s_addr = inAddress; } #else if (inet_aton(addr, &sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { __redisSetError(c,REDIS_ERR_OTHER, sdscatprintf(sdsempty(),"Can't resolve: %s",addr)); close(s); return REDIS_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } #endif #ifdef _WIN32 if (connect((SOCKET)s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { errno = WSAGetLastError(); if ((errno == WSAEINVAL) || (errno == WSAEWOULDBLOCK)) errno = EINPROGRESS; #else if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { #endif if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { __redisSetError(c,REDIS_ERR_IO,NULL); #ifdef _WIN32 closesocket(s); #else close(s); #endif return REDIS_ERR; } } if (redisSetTcpNoDelay(c,s) != REDIS_OK) { #ifdef _WIN32 closesocket(s); #else close(s); #endif return REDIS_ERR; } c->fd = s; c->flags |= REDIS_CONNECTED; return REDIS_OK; } int redisContextConnectUnix(redisContext *c, const char *path) { #ifdef _WIN32 (void) path; __redisSetError(c,REDIS_ERR_IO,NULL); return REDIS_ERR; #else int s; int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_un sa; if ((s = redisCreateSocket(c,AF_LOCAL)) == REDIS_ERR) return REDIS_ERR; if (!blocking && redisSetNonBlock(c,s) != REDIS_OK) return REDIS_ERR; sa.sun_family = AF_LOCAL; strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1); if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { __redisSetError(c,REDIS_ERR_IO,NULL); close(s); return REDIS_ERR; } } c->fd = s; c->flags |= REDIS_CONNECTED; return REDIS_OK; #endif }
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout) { int s; int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_in sa; #ifdef HIREDIS_WIN int ssa = sizeof(sa); char buf[255]; snprintf(buf, 255, "%s:%d", addr, port); #endif if ((s = redisCreateSocket(c,AF_INET)) < 0) return REDIS_ERR; if (redisSetBlocking(c,s,0) != REDIS_OK) return REDIS_ERR; sa.sin_family = AF_INET; sa.sin_port = htons(port); #ifdef HIREDIS_WIN if (WSAStringToAddress(buf, AF_INET, NULL, (LPSOCKADDR)&sa, &ssa) == 0) { #else if (inet_pton(AF_INET, addr, &sa.sin_addr) == 0) { #endif struct hostent *he; he = gethostbyname(addr); if (he == NULL) { char buf[128]; snprintf(buf,sizeof(buf),"Can't resolve: %s", addr); __redisSetError(c,REDIS_ERR_OTHER,buf); close(s); return REDIS_ERR; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } #ifdef HIREDIS_WIN else { int wserr = WSAGetLastError(); switch (wserr) { case WSAEFAULT: printf("The specified Address buffer is too small. Pass in a larger buffer."); break; case WSAEINVAL: printf("Unable to translate the string into a sockaddr."); break; case WSANOTINITIALISED: printf("ws2.dll has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions."); break; case WSA_NOT_ENOUGH_MEMORY: printf("There was insufficient memory to perform the operation."); break; default: break; } } #endif if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { SETERRNO; if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { if (redisContextWaitReady(c,s,timeout) != REDIS_OK) return REDIS_ERR; } } /* Reset socket to be blocking after connect(2). */ if (blocking && redisSetBlocking(c,s,1) != REDIS_OK) return REDIS_ERR; if (redisSetTcpNoDelay(c,s) != REDIS_OK) return REDIS_ERR; c->fd = s; c->flags |= REDIS_CONNECTED; return REDIS_OK; } #ifndef HIREDIS_WIN int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout) { int s; int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_un sa; if ((s = redisCreateSocket(c,AF_LOCAL)) < 0) return REDIS_ERR; if (redisSetBlocking(c,s,0) != REDIS_OK) return REDIS_ERR; sa.sun_family = AF_LOCAL; strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1); if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { if (redisContextWaitReady(c,s,timeout) != REDIS_OK) return REDIS_ERR; } } /* Reset socket to be blocking after connect(2). */ if (blocking && redisSetBlocking(c,s,1) != REDIS_OK) return REDIS_ERR; c->fd = s; c->flags |= REDIS_CONNECTED; return REDIS_OK; }