redis-client 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +1 -2
  4. data/Gemfile.lock +1 -2
  5. data/README.md +5 -9
  6. data/Rakefile +41 -22
  7. data/lib/redis_client/version.rb +1 -1
  8. data/lib/redis_client.rb +1 -6
  9. data/redis-client.gemspec +2 -4
  10. metadata +6 -56
  11. data/.rubocop.yml +0 -191
  12. data/ext/redis_client/hiredis/export.clang +0 -2
  13. data/ext/redis_client/hiredis/export.gcc +0 -7
  14. data/ext/redis_client/hiredis/extconf.rb +0 -69
  15. data/ext/redis_client/hiredis/hiredis_connection.c +0 -708
  16. data/ext/redis_client/hiredis/vendor/.gitignore +0 -9
  17. data/ext/redis_client/hiredis/vendor/.travis.yml +0 -131
  18. data/ext/redis_client/hiredis/vendor/CHANGELOG.md +0 -364
  19. data/ext/redis_client/hiredis/vendor/CMakeLists.txt +0 -165
  20. data/ext/redis_client/hiredis/vendor/COPYING +0 -29
  21. data/ext/redis_client/hiredis/vendor/Makefile +0 -308
  22. data/ext/redis_client/hiredis/vendor/README.md +0 -664
  23. data/ext/redis_client/hiredis/vendor/adapters/ae.h +0 -130
  24. data/ext/redis_client/hiredis/vendor/adapters/glib.h +0 -156
  25. data/ext/redis_client/hiredis/vendor/adapters/ivykis.h +0 -84
  26. data/ext/redis_client/hiredis/vendor/adapters/libev.h +0 -179
  27. data/ext/redis_client/hiredis/vendor/adapters/libevent.h +0 -175
  28. data/ext/redis_client/hiredis/vendor/adapters/libuv.h +0 -117
  29. data/ext/redis_client/hiredis/vendor/adapters/macosx.h +0 -115
  30. data/ext/redis_client/hiredis/vendor/adapters/qt.h +0 -135
  31. data/ext/redis_client/hiredis/vendor/alloc.c +0 -86
  32. data/ext/redis_client/hiredis/vendor/alloc.h +0 -91
  33. data/ext/redis_client/hiredis/vendor/appveyor.yml +0 -24
  34. data/ext/redis_client/hiredis/vendor/async.c +0 -887
  35. data/ext/redis_client/hiredis/vendor/async.h +0 -147
  36. data/ext/redis_client/hiredis/vendor/async_private.h +0 -75
  37. data/ext/redis_client/hiredis/vendor/dict.c +0 -352
  38. data/ext/redis_client/hiredis/vendor/dict.h +0 -126
  39. data/ext/redis_client/hiredis/vendor/fmacros.h +0 -12
  40. data/ext/redis_client/hiredis/vendor/hiredis-config.cmake.in +0 -13
  41. data/ext/redis_client/hiredis/vendor/hiredis.c +0 -1174
  42. data/ext/redis_client/hiredis/vendor/hiredis.h +0 -336
  43. data/ext/redis_client/hiredis/vendor/hiredis.pc.in +0 -12
  44. data/ext/redis_client/hiredis/vendor/hiredis_ssl-config.cmake.in +0 -13
  45. data/ext/redis_client/hiredis/vendor/hiredis_ssl.h +0 -157
  46. data/ext/redis_client/hiredis/vendor/hiredis_ssl.pc.in +0 -12
  47. data/ext/redis_client/hiredis/vendor/net.c +0 -612
  48. data/ext/redis_client/hiredis/vendor/net.h +0 -56
  49. data/ext/redis_client/hiredis/vendor/read.c +0 -739
  50. data/ext/redis_client/hiredis/vendor/read.h +0 -129
  51. data/ext/redis_client/hiredis/vendor/sds.c +0 -1289
  52. data/ext/redis_client/hiredis/vendor/sds.h +0 -278
  53. data/ext/redis_client/hiredis/vendor/sdsalloc.h +0 -44
  54. data/ext/redis_client/hiredis/vendor/sockcompat.c +0 -248
  55. data/ext/redis_client/hiredis/vendor/sockcompat.h +0 -92
  56. data/ext/redis_client/hiredis/vendor/ssl.c +0 -544
  57. data/ext/redis_client/hiredis/vendor/test.c +0 -1401
  58. data/ext/redis_client/hiredis/vendor/test.sh +0 -78
  59. data/ext/redis_client/hiredis/vendor/win32.h +0 -56
  60. data/lib/redis_client/hiredis_connection.rb +0 -93
@@ -1,612 +0,0 @@
1
- /* Extracted from anet.c to work properly with Hiredis error reporting.
2
- *
3
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
4
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
5
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
6
- * Jan-Erik Rediger <janerik at fnordig dot com>
7
- *
8
- * All rights reserved.
9
- *
10
- * Redistribution and use in source and binary forms, with or without
11
- * modification, are permitted provided that the following conditions are met:
12
- *
13
- * * Redistributions of source code must retain the above copyright notice,
14
- * this list of conditions and the following disclaimer.
15
- * * Redistributions in binary form must reproduce the above copyright
16
- * notice, this list of conditions and the following disclaimer in the
17
- * documentation and/or other materials provided with the distribution.
18
- * * Neither the name of Redis nor the names of its contributors may be used
19
- * to endorse or promote products derived from this software without
20
- * specific prior written permission.
21
- *
22
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
- * POSSIBILITY OF SUCH DAMAGE.
33
- */
34
-
35
- #include "fmacros.h"
36
- #include <sys/types.h>
37
- #include <fcntl.h>
38
- #include <string.h>
39
- #include <errno.h>
40
- #include <stdarg.h>
41
- #include <stdio.h>
42
- #include <limits.h>
43
- #include <stdlib.h>
44
-
45
- #include "net.h"
46
- #include "sds.h"
47
- #include "sockcompat.h"
48
- #include "win32.h"
49
-
50
- /* Defined in hiredis.c */
51
- void __redisSetError(redisContext *c, int type, const char *str);
52
-
53
- void redisNetClose(redisContext *c) {
54
- if (c && c->fd != REDIS_INVALID_FD) {
55
- close(c->fd);
56
- c->fd = REDIS_INVALID_FD;
57
- }
58
- }
59
-
60
- ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) {
61
- ssize_t nread = recv(c->fd, buf, bufcap, 0);
62
- if (nread == -1) {
63
- if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
64
- /* Try again later */
65
- return 0;
66
- } else if(errno == ETIMEDOUT && (c->flags & REDIS_BLOCK)) {
67
- /* especially in windows */
68
- __redisSetError(c, REDIS_ERR_TIMEOUT, "recv timeout");
69
- return -1;
70
- } else {
71
- __redisSetError(c, REDIS_ERR_IO, NULL);
72
- return -1;
73
- }
74
- } else if (nread == 0) {
75
- __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection");
76
- return -1;
77
- } else {
78
- return nread;
79
- }
80
- }
81
-
82
- ssize_t redisNetWrite(redisContext *c) {
83
- ssize_t nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0);
84
- if (nwritten < 0) {
85
- if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
86
- /* Try again later */
87
- } else {
88
- __redisSetError(c, REDIS_ERR_IO, NULL);
89
- return -1;
90
- }
91
- }
92
- return nwritten;
93
- }
94
-
95
- static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) {
96
- int errorno = errno; /* snprintf() may change errno */
97
- char buf[128] = { 0 };
98
- size_t len = 0;
99
-
100
- if (prefix != NULL)
101
- len = snprintf(buf,sizeof(buf),"%s: ",prefix);
102
- strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len);
103
- __redisSetError(c,type,buf);
104
- }
105
-
106
- static int redisSetReuseAddr(redisContext *c) {
107
- int on = 1;
108
- if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
109
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
110
- redisNetClose(c);
111
- return REDIS_ERR;
112
- }
113
- return REDIS_OK;
114
- }
115
-
116
- static int redisCreateSocket(redisContext *c, int type) {
117
- redisFD s;
118
- if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) {
119
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
120
- return REDIS_ERR;
121
- }
122
- c->fd = s;
123
- if (type == AF_INET) {
124
- if (redisSetReuseAddr(c) == REDIS_ERR) {
125
- return REDIS_ERR;
126
- }
127
- }
128
- return REDIS_OK;
129
- }
130
-
131
- static int redisSetBlocking(redisContext *c, int blocking) {
132
- #ifndef _WIN32
133
- int flags;
134
-
135
- /* Set the socket nonblocking.
136
- * Note that fcntl(2) for F_GETFL and F_SETFL can't be
137
- * interrupted by a signal. */
138
- if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
139
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
140
- redisNetClose(c);
141
- return REDIS_ERR;
142
- }
143
-
144
- if (blocking)
145
- flags &= ~O_NONBLOCK;
146
- else
147
- flags |= O_NONBLOCK;
148
-
149
- if (fcntl(c->fd, F_SETFL, flags) == -1) {
150
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
151
- redisNetClose(c);
152
- return REDIS_ERR;
153
- }
154
- #else
155
- u_long mode = blocking ? 0 : 1;
156
- if (ioctl(c->fd, FIONBIO, &mode) == -1) {
157
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, "ioctl(FIONBIO)");
158
- redisNetClose(c);
159
- return REDIS_ERR;
160
- }
161
- #endif /* _WIN32 */
162
- return REDIS_OK;
163
- }
164
-
165
- int redisKeepAlive(redisContext *c, int interval) {
166
- int val = 1;
167
- redisFD fd = c->fd;
168
-
169
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){
170
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
171
- return REDIS_ERR;
172
- }
173
-
174
- val = interval;
175
-
176
- #if defined(__APPLE__) && defined(__MACH__)
177
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) {
178
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
179
- return REDIS_ERR;
180
- }
181
- #else
182
- #if defined(__GLIBC__) && !defined(__FreeBSD_kernel__)
183
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
184
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
185
- return REDIS_ERR;
186
- }
187
-
188
- val = interval/3;
189
- if (val == 0) val = 1;
190
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) {
191
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
192
- return REDIS_ERR;
193
- }
194
-
195
- val = 3;
196
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
197
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
198
- return REDIS_ERR;
199
- }
200
- #endif
201
- #endif
202
-
203
- return REDIS_OK;
204
- }
205
-
206
- int redisSetTcpNoDelay(redisContext *c) {
207
- int yes = 1;
208
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
209
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
210
- redisNetClose(c);
211
- return REDIS_ERR;
212
- }
213
- return REDIS_OK;
214
- }
215
-
216
- #define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
217
-
218
- static int redisContextTimeoutMsec(redisContext *c, long *result)
219
- {
220
- const struct timeval *timeout = c->connect_timeout;
221
- long msec = -1;
222
-
223
- /* Only use timeout when not NULL. */
224
- if (timeout != NULL) {
225
- if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
226
- *result = msec;
227
- return REDIS_ERR;
228
- }
229
-
230
- msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
231
-
232
- if (msec < 0 || msec > INT_MAX) {
233
- msec = INT_MAX;
234
- }
235
- }
236
-
237
- *result = msec;
238
- return REDIS_OK;
239
- }
240
-
241
- static int redisContextWaitReady(redisContext *c, long msec) {
242
- struct pollfd wfd[1];
243
-
244
- wfd[0].fd = c->fd;
245
- wfd[0].events = POLLOUT;
246
-
247
- if (errno == EINPROGRESS) {
248
- int res;
249
-
250
- if ((res = poll(wfd, 1, msec)) == -1) {
251
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
252
- redisNetClose(c);
253
- return REDIS_ERR;
254
- } else if (res == 0) {
255
- errno = ETIMEDOUT;
256
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
257
- redisNetClose(c);
258
- return REDIS_ERR;
259
- }
260
-
261
- if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) {
262
- redisCheckSocketError(c);
263
- return REDIS_ERR;
264
- }
265
-
266
- return REDIS_OK;
267
- }
268
-
269
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
270
- redisNetClose(c);
271
- return REDIS_ERR;
272
- }
273
-
274
- int redisCheckConnectDone(redisContext *c, int *completed) {
275
- int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen);
276
- if (rc == 0) {
277
- *completed = 1;
278
- return REDIS_OK;
279
- }
280
- switch (errno) {
281
- case EISCONN:
282
- *completed = 1;
283
- return REDIS_OK;
284
- case EALREADY:
285
- case EINPROGRESS:
286
- case EWOULDBLOCK:
287
- *completed = 0;
288
- return REDIS_OK;
289
- default:
290
- return REDIS_ERR;
291
- }
292
- }
293
-
294
- int redisCheckSocketError(redisContext *c) {
295
- int err = 0, errno_saved = errno;
296
- socklen_t errlen = sizeof(err);
297
-
298
- if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
299
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
300
- return REDIS_ERR;
301
- }
302
-
303
- if (err == 0) {
304
- err = errno_saved;
305
- }
306
-
307
- if (err) {
308
- errno = err;
309
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
310
- return REDIS_ERR;
311
- }
312
-
313
- return REDIS_OK;
314
- }
315
-
316
- int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
317
- const void *to_ptr = &tv;
318
- size_t to_sz = sizeof(tv);
319
-
320
- if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,to_ptr,to_sz) == -1) {
321
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
322
- return REDIS_ERR;
323
- }
324
- if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,to_ptr,to_sz) == -1) {
325
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)");
326
- return REDIS_ERR;
327
- }
328
- return REDIS_OK;
329
- }
330
-
331
- int redisContextUpdateConnectTimeout(redisContext *c, const struct timeval *timeout) {
332
- /* Same timeval struct, short circuit */
333
- if (c->connect_timeout == timeout)
334
- return REDIS_OK;
335
-
336
- /* Allocate context timeval if we need to */
337
- if (c->connect_timeout == NULL) {
338
- c->connect_timeout = hi_malloc(sizeof(*c->connect_timeout));
339
- if (c->connect_timeout == NULL)
340
- return REDIS_ERR;
341
- }
342
-
343
- memcpy(c->connect_timeout, timeout, sizeof(*c->connect_timeout));
344
- return REDIS_OK;
345
- }
346
-
347
- int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout) {
348
- /* Same timeval struct, short circuit */
349
- if (c->command_timeout == timeout)
350
- return REDIS_OK;
351
-
352
- /* Allocate context timeval if we need to */
353
- if (c->command_timeout == NULL) {
354
- c->command_timeout = hi_malloc(sizeof(*c->command_timeout));
355
- if (c->command_timeout == NULL)
356
- return REDIS_ERR;
357
- }
358
-
359
- memcpy(c->command_timeout, timeout, sizeof(*c->command_timeout));
360
- return REDIS_OK;
361
- }
362
-
363
- static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
364
- const struct timeval *timeout,
365
- const char *source_addr) {
366
- redisFD s;
367
- int rv, n;
368
- char _port[6]; /* strlen("65535"); */
369
- struct addrinfo hints, *servinfo, *bservinfo, *p, *b;
370
- int blocking = (c->flags & REDIS_BLOCK);
371
- int reuseaddr = (c->flags & REDIS_REUSEADDR);
372
- int reuses = 0;
373
- long timeout_msec = -1;
374
-
375
- servinfo = NULL;
376
- c->connection_type = REDIS_CONN_TCP;
377
- c->tcp.port = port;
378
-
379
- /* We need to take possession of the passed parameters
380
- * to make them reusable for a reconnect.
381
- * We also carefully check we don't free data we already own,
382
- * as in the case of the reconnect method.
383
- *
384
- * This is a bit ugly, but atleast it works and doesn't leak memory.
385
- **/
386
- if (c->tcp.host != addr) {
387
- hi_free(c->tcp.host);
388
-
389
- c->tcp.host = hi_strdup(addr);
390
- if (c->tcp.host == NULL)
391
- goto oom;
392
- }
393
-
394
- if (timeout) {
395
- if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR)
396
- goto oom;
397
- } else {
398
- hi_free(c->connect_timeout);
399
- c->connect_timeout = NULL;
400
- }
401
-
402
- if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) {
403
- __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified");
404
- goto error;
405
- }
406
-
407
- if (source_addr == NULL) {
408
- hi_free(c->tcp.source_addr);
409
- c->tcp.source_addr = NULL;
410
- } else if (c->tcp.source_addr != source_addr) {
411
- hi_free(c->tcp.source_addr);
412
- c->tcp.source_addr = hi_strdup(source_addr);
413
- }
414
-
415
- snprintf(_port, 6, "%d", port);
416
- memset(&hints,0,sizeof(hints));
417
- hints.ai_family = AF_INET;
418
- hints.ai_socktype = SOCK_STREAM;
419
-
420
- /* Try with IPv6 if no IPv4 address was found. We do it in this order since
421
- * in a Redis client you can't afford to test if you have IPv6 connectivity
422
- * as this would add latency to every connect. Otherwise a more sensible
423
- * route could be: Use IPv6 if both addresses are available and there is IPv6
424
- * connectivity. */
425
- if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) {
426
- hints.ai_family = AF_INET6;
427
- if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
428
- __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
429
- return REDIS_ERR;
430
- }
431
- }
432
- for (p = servinfo; p != NULL; p = p->ai_next) {
433
- addrretry:
434
- if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD)
435
- continue;
436
-
437
- c->fd = s;
438
- if (redisSetBlocking(c,0) != REDIS_OK)
439
- goto error;
440
- if (c->tcp.source_addr) {
441
- int bound = 0;
442
- /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
443
- if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) {
444
- char buf[128];
445
- snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv));
446
- __redisSetError(c,REDIS_ERR_OTHER,buf);
447
- goto error;
448
- }
449
-
450
- if (reuseaddr) {
451
- n = 1;
452
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n,
453
- sizeof(n)) < 0) {
454
- freeaddrinfo(bservinfo);
455
- goto error;
456
- }
457
- }
458
-
459
- for (b = bservinfo; b != NULL; b = b->ai_next) {
460
- if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
461
- bound = 1;
462
- break;
463
- }
464
- }
465
- freeaddrinfo(bservinfo);
466
- if (!bound) {
467
- char buf[128];
468
- snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno));
469
- __redisSetError(c,REDIS_ERR_OTHER,buf);
470
- goto error;
471
- }
472
- }
473
-
474
- /* For repeat connection */
475
- hi_free(c->saddr);
476
- c->saddr = hi_malloc(p->ai_addrlen);
477
- if (c->saddr == NULL)
478
- goto oom;
479
-
480
- memcpy(c->saddr, p->ai_addr, p->ai_addrlen);
481
- c->addrlen = p->ai_addrlen;
482
-
483
- if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
484
- if (errno == EHOSTUNREACH) {
485
- redisNetClose(c);
486
- continue;
487
- } else if (errno == EINPROGRESS) {
488
- if (blocking) {
489
- goto wait_for_ready;
490
- }
491
- /* This is ok.
492
- * Note that even when it's in blocking mode, we unset blocking
493
- * for `connect()`
494
- */
495
- } else if (errno == EADDRNOTAVAIL && reuseaddr) {
496
- if (++reuses >= REDIS_CONNECT_RETRIES) {
497
- goto error;
498
- } else {
499
- redisNetClose(c);
500
- goto addrretry;
501
- }
502
- } else {
503
- wait_for_ready:
504
- if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
505
- goto error;
506
- if (redisSetTcpNoDelay(c) != REDIS_OK)
507
- goto error;
508
- }
509
- }
510
- if (blocking && redisSetBlocking(c,1) != REDIS_OK)
511
- goto error;
512
-
513
- c->flags |= REDIS_CONNECTED;
514
- rv = REDIS_OK;
515
- goto end;
516
- }
517
- if (p == NULL) {
518
- char buf[128];
519
- snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno));
520
- __redisSetError(c,REDIS_ERR_OTHER,buf);
521
- goto error;
522
- }
523
-
524
- oom:
525
- __redisSetError(c, REDIS_ERR_OOM, "Out of memory");
526
- error:
527
- rv = REDIS_ERR;
528
- end:
529
- if(servinfo) {
530
- freeaddrinfo(servinfo);
531
- }
532
-
533
- return rv; // Need to return REDIS_OK if alright
534
- }
535
-
536
- int redisContextConnectTcp(redisContext *c, const char *addr, int port,
537
- const struct timeval *timeout) {
538
- return _redisContextConnectTcp(c, addr, port, timeout, NULL);
539
- }
540
-
541
- int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
542
- const struct timeval *timeout,
543
- const char *source_addr) {
544
- return _redisContextConnectTcp(c, addr, port, timeout, source_addr);
545
- }
546
-
547
- int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
548
- #ifndef _WIN32
549
- int blocking = (c->flags & REDIS_BLOCK);
550
- struct sockaddr_un *sa;
551
- long timeout_msec = -1;
552
-
553
- if (redisCreateSocket(c,AF_UNIX) < 0)
554
- return REDIS_ERR;
555
- if (redisSetBlocking(c,0) != REDIS_OK)
556
- return REDIS_ERR;
557
-
558
- c->connection_type = REDIS_CONN_UNIX;
559
- if (c->unix_sock.path != path) {
560
- hi_free(c->unix_sock.path);
561
-
562
- c->unix_sock.path = hi_strdup(path);
563
- if (c->unix_sock.path == NULL)
564
- goto oom;
565
- }
566
-
567
- if (timeout) {
568
- if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR)
569
- goto oom;
570
- } else {
571
- hi_free(c->connect_timeout);
572
- c->connect_timeout = NULL;
573
- }
574
-
575
- if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
576
- return REDIS_ERR;
577
-
578
- /* Don't leak sockaddr if we're reconnecting */
579
- if (c->saddr) hi_free(c->saddr);
580
-
581
- sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un)));
582
- if (sa == NULL)
583
- goto oom;
584
-
585
- c->addrlen = sizeof(struct sockaddr_un);
586
- sa->sun_family = AF_UNIX;
587
- strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
588
- if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) {
589
- if (errno == EINPROGRESS && !blocking) {
590
- /* This is ok. */
591
- } else {
592
- if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
593
- return REDIS_ERR;
594
- }
595
- }
596
-
597
- /* Reset socket to be blocking after connect(2). */
598
- if (blocking && redisSetBlocking(c,1) != REDIS_OK)
599
- return REDIS_ERR;
600
-
601
- c->flags |= REDIS_CONNECTED;
602
- return REDIS_OK;
603
- #else
604
- /* We currently do not support Unix sockets for Windows. */
605
- /* TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */
606
- errno = EPROTONOSUPPORT;
607
- return REDIS_ERR;
608
- #endif /* _WIN32 */
609
- oom:
610
- __redisSetError(c, REDIS_ERR_OOM, "Out of memory");
611
- return REDIS_ERR;
612
- }
@@ -1,56 +0,0 @@
1
- /* Extracted from anet.c to work properly with Hiredis error reporting.
2
- *
3
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
4
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
5
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
6
- * Jan-Erik Rediger <janerik at fnordig dot com>
7
- *
8
- * All rights reserved.
9
- *
10
- * Redistribution and use in source and binary forms, with or without
11
- * modification, are permitted provided that the following conditions are met:
12
- *
13
- * * Redistributions of source code must retain the above copyright notice,
14
- * this list of conditions and the following disclaimer.
15
- * * Redistributions in binary form must reproduce the above copyright
16
- * notice, this list of conditions and the following disclaimer in the
17
- * documentation and/or other materials provided with the distribution.
18
- * * Neither the name of Redis nor the names of its contributors may be used
19
- * to endorse or promote products derived from this software without
20
- * specific prior written permission.
21
- *
22
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
- * POSSIBILITY OF SUCH DAMAGE.
33
- */
34
-
35
- #ifndef __NET_H
36
- #define __NET_H
37
-
38
- #include "hiredis.h"
39
-
40
- void redisNetClose(redisContext *c);
41
- ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap);
42
- ssize_t redisNetWrite(redisContext *c);
43
-
44
- int redisCheckSocketError(redisContext *c);
45
- int redisContextSetTimeout(redisContext *c, const struct timeval tv);
46
- int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout);
47
- int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
48
- const struct timeval *timeout,
49
- const char *source_addr);
50
- int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout);
51
- int redisKeepAlive(redisContext *c, int interval);
52
- int redisCheckConnectDone(redisContext *c, int *completed);
53
-
54
- int redisSetTcpNoDelay(redisContext *c);
55
-
56
- #endif