hiredis-futureproof 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +28 -0
  3. data/Rakefile +53 -0
  4. data/ext/hiredis_ext/connection.c +611 -0
  5. data/ext/hiredis_ext/extconf.rb +48 -0
  6. data/ext/hiredis_ext/hiredis_ext.c +15 -0
  7. data/ext/hiredis_ext/hiredis_ext.h +44 -0
  8. data/ext/hiredis_ext/reader.c +124 -0
  9. data/lib/hiredis/connection.rb +10 -0
  10. data/lib/hiredis/ext/connection.rb +29 -0
  11. data/lib/hiredis/ext/reader.rb +2 -0
  12. data/lib/hiredis/reader.rb +10 -0
  13. data/lib/hiredis/ruby/connection.rb +316 -0
  14. data/lib/hiredis/ruby/reader.rb +183 -0
  15. data/lib/hiredis/version.rb +3 -0
  16. data/lib/hiredis.rb +2 -0
  17. data/vendor/hiredis/COPYING +29 -0
  18. data/vendor/hiredis/Makefile +308 -0
  19. data/vendor/hiredis/alloc.c +86 -0
  20. data/vendor/hiredis/alloc.h +91 -0
  21. data/vendor/hiredis/async.c +892 -0
  22. data/vendor/hiredis/async.h +147 -0
  23. data/vendor/hiredis/async_private.h +75 -0
  24. data/vendor/hiredis/dict.c +352 -0
  25. data/vendor/hiredis/dict.h +126 -0
  26. data/vendor/hiredis/fmacros.h +12 -0
  27. data/vendor/hiredis/hiredis.c +1173 -0
  28. data/vendor/hiredis/hiredis.h +336 -0
  29. data/vendor/hiredis/hiredis_ssl.h +127 -0
  30. data/vendor/hiredis/net.c +612 -0
  31. data/vendor/hiredis/net.h +56 -0
  32. data/vendor/hiredis/read.c +739 -0
  33. data/vendor/hiredis/read.h +129 -0
  34. data/vendor/hiredis/sds.c +1289 -0
  35. data/vendor/hiredis/sds.h +278 -0
  36. data/vendor/hiredis/sdsalloc.h +44 -0
  37. data/vendor/hiredis/sockcompat.c +248 -0
  38. data/vendor/hiredis/sockcompat.h +92 -0
  39. data/vendor/hiredis/ssl.c +526 -0
  40. data/vendor/hiredis/test.c +1387 -0
  41. data/vendor/hiredis/win32.h +56 -0
  42. metadata +128 -0
@@ -0,0 +1,336 @@
1
+ /*
2
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
3
+ * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
4
+ * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
5
+ * Jan-Erik Rediger <janerik at fnordig dot com>
6
+ *
7
+ * All rights reserved.
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions are met:
11
+ *
12
+ * * Redistributions of source code must retain the above copyright notice,
13
+ * this list of conditions and the following disclaimer.
14
+ * * Redistributions in binary form must reproduce the above copyright
15
+ * notice, this list of conditions and the following disclaimer in the
16
+ * documentation and/or other materials provided with the distribution.
17
+ * * Neither the name of Redis nor the names of its contributors may be used
18
+ * to endorse or promote products derived from this software without
19
+ * specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ * POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+
34
+ #ifndef __HIREDIS_H
35
+ #define __HIREDIS_H
36
+ #include "read.h"
37
+ #include <stdarg.h> /* for va_list */
38
+ #ifndef _MSC_VER
39
+ #include <sys/time.h> /* for struct timeval */
40
+ #else
41
+ struct timeval; /* forward declaration */
42
+ typedef long long ssize_t;
43
+ #endif
44
+ #include <stdint.h> /* uintXX_t, etc */
45
+ #include "sds.h" /* for sds */
46
+ #include "alloc.h" /* for allocation wrappers */
47
+
48
+ #define HIREDIS_MAJOR 1
49
+ #define HIREDIS_MINOR 0
50
+ #define HIREDIS_PATCH 1
51
+ #define HIREDIS_SONAME 1.0.1-dev
52
+
53
+ /* Connection type can be blocking or non-blocking and is set in the
54
+ * least significant bit of the flags field in redisContext. */
55
+ #define REDIS_BLOCK 0x1
56
+
57
+ /* Connection may be disconnected before being free'd. The second bit
58
+ * in the flags field is set when the context is connected. */
59
+ #define REDIS_CONNECTED 0x2
60
+
61
+ /* The async API might try to disconnect cleanly and flush the output
62
+ * buffer and read all subsequent replies before disconnecting.
63
+ * This flag means no new commands can come in and the connection
64
+ * should be terminated once all replies have been read. */
65
+ #define REDIS_DISCONNECTING 0x4
66
+
67
+ /* Flag specific to the async API which means that the context should be clean
68
+ * up as soon as possible. */
69
+ #define REDIS_FREEING 0x8
70
+
71
+ /* Flag that is set when an async callback is executed. */
72
+ #define REDIS_IN_CALLBACK 0x10
73
+
74
+ /* Flag that is set when the async context has one or more subscriptions. */
75
+ #define REDIS_SUBSCRIBED 0x20
76
+
77
+ /* Flag that is set when monitor mode is active */
78
+ #define REDIS_MONITORING 0x40
79
+
80
+ /* Flag that is set when we should set SO_REUSEADDR before calling bind() */
81
+ #define REDIS_REUSEADDR 0x80
82
+
83
+ /**
84
+ * Flag that indicates the user does not want the context to
85
+ * be automatically freed upon error
86
+ */
87
+ #define REDIS_NO_AUTO_FREE 0x200
88
+
89
+ #define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
90
+
91
+ /* number of times we retry to connect in the case of EADDRNOTAVAIL and
92
+ * SO_REUSEADDR is being used. */
93
+ #define REDIS_CONNECT_RETRIES 10
94
+
95
+ /* Forward declarations for structs defined elsewhere */
96
+ struct redisAsyncContext;
97
+ struct redisContext;
98
+
99
+ /* RESP3 push helpers and callback prototypes */
100
+ #define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH)
101
+ typedef void (redisPushFn)(void *, void *);
102
+ typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *);
103
+
104
+ #ifdef __cplusplus
105
+ extern "C" {
106
+ #endif
107
+
108
+ /* This is the reply object returned by redisCommand() */
109
+ typedef struct redisReply {
110
+ int type; /* REDIS_REPLY_* */
111
+ long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
112
+ double dval; /* The double when type is REDIS_REPLY_DOUBLE */
113
+ size_t len; /* Length of string */
114
+ char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
115
+ REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */
116
+ char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null
117
+ terminated 3 character content type, such as "txt". */
118
+ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
119
+ struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
120
+ } redisReply;
121
+
122
+ redisReader *redisReaderCreate(void);
123
+
124
+ /* Function to free the reply objects hiredis returns by default. */
125
+ void freeReplyObject(void *reply);
126
+
127
+ /* Functions to format a command according to the protocol. */
128
+ int redisvFormatCommand(char **target, const char *format, va_list ap);
129
+ int redisFormatCommand(char **target, const char *format, ...);
130
+ int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
131
+ int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
132
+ void redisFreeCommand(char *cmd);
133
+ void redisFreeSdsCommand(sds cmd);
134
+
135
+ enum redisConnectionType {
136
+ REDIS_CONN_TCP,
137
+ REDIS_CONN_UNIX,
138
+ REDIS_CONN_USERFD
139
+ };
140
+
141
+ struct redisSsl;
142
+
143
+ #define REDIS_OPT_NONBLOCK 0x01
144
+ #define REDIS_OPT_REUSEADDR 0x02
145
+
146
+ /**
147
+ * Don't automatically free the async object on a connection failure,
148
+ * or other implicit conditions. Only free on an explicit call to disconnect() or free()
149
+ */
150
+ #define REDIS_OPT_NOAUTOFREE 0x04
151
+
152
+ /* Don't automatically intercept and free RESP3 PUSH replies. */
153
+ #define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
154
+
155
+ /* In Unix systems a file descriptor is a regular signed int, with -1
156
+ * representing an invalid descriptor. In Windows it is a SOCKET
157
+ * (32- or 64-bit unsigned integer depending on the architecture), where
158
+ * all bits set (~0) is INVALID_SOCKET. */
159
+ #ifndef _WIN32
160
+ typedef int redisFD;
161
+ #define REDIS_INVALID_FD -1
162
+ #else
163
+ #ifdef _WIN64
164
+ typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */
165
+ #else
166
+ typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */
167
+ #endif
168
+ #define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */
169
+ #endif
170
+
171
+ typedef struct {
172
+ /*
173
+ * the type of connection to use. This also indicates which
174
+ * `endpoint` member field to use
175
+ */
176
+ int type;
177
+ /* bit field of REDIS_OPT_xxx */
178
+ int options;
179
+ /* timeout value for connect operation. If NULL, no timeout is used */
180
+ const struct timeval *connect_timeout;
181
+ /* timeout value for commands. If NULL, no timeout is used. This can be
182
+ * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */
183
+ const struct timeval *command_timeout;
184
+ union {
185
+ /** use this field for tcp/ip connections */
186
+ struct {
187
+ const char *source_addr;
188
+ const char *ip;
189
+ int port;
190
+ } tcp;
191
+ /** use this field for unix domain sockets */
192
+ const char *unix_socket;
193
+ /**
194
+ * use this field to have hiredis operate an already-open
195
+ * file descriptor */
196
+ redisFD fd;
197
+ } endpoint;
198
+
199
+ /* Optional user defined data/destructor */
200
+ void *privdata;
201
+ void (*free_privdata)(void *);
202
+
203
+ /* A user defined PUSH message callback */
204
+ redisPushFn *push_cb;
205
+ redisAsyncPushFn *async_push_cb;
206
+ } redisOptions;
207
+
208
+ /**
209
+ * Helper macros to initialize options to their specified fields.
210
+ */
211
+ #define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
212
+ (opts)->type = REDIS_CONN_TCP; \
213
+ (opts)->endpoint.tcp.ip = ip_; \
214
+ (opts)->endpoint.tcp.port = port_;
215
+
216
+ #define REDIS_OPTIONS_SET_UNIX(opts, path) \
217
+ (opts)->type = REDIS_CONN_UNIX; \
218
+ (opts)->endpoint.unix_socket = path;
219
+
220
+ #define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \
221
+ (opts)->privdata = data; \
222
+ (opts)->free_privdata = dtor; \
223
+
224
+ typedef struct redisContextFuncs {
225
+ void (*free_privctx)(void *);
226
+ void (*async_read)(struct redisAsyncContext *);
227
+ void (*async_write)(struct redisAsyncContext *);
228
+ ssize_t (*read)(struct redisContext *, char *, size_t);
229
+ ssize_t (*write)(struct redisContext *);
230
+ } redisContextFuncs;
231
+
232
+ /* Context for a connection to Redis */
233
+ typedef struct redisContext {
234
+ const redisContextFuncs *funcs; /* Function table */
235
+
236
+ int err; /* Error flags, 0 when there is no error */
237
+ char errstr[128]; /* String representation of error when applicable */
238
+ redisFD fd;
239
+ int flags;
240
+ char *obuf; /* Write buffer */
241
+ redisReader *reader; /* Protocol reader */
242
+
243
+ enum redisConnectionType connection_type;
244
+ struct timeval *connect_timeout;
245
+ struct timeval *command_timeout;
246
+
247
+ struct {
248
+ char *host;
249
+ char *source_addr;
250
+ int port;
251
+ } tcp;
252
+
253
+ struct {
254
+ char *path;
255
+ } unix_sock;
256
+
257
+ /* For non-blocking connect */
258
+ struct sockadr *saddr;
259
+ size_t addrlen;
260
+
261
+ /* Optional data and corresponding destructor users can use to provide
262
+ * context to a given redisContext. Not used by hiredis. */
263
+ void *privdata;
264
+ void (*free_privdata)(void *);
265
+
266
+ /* Internal context pointer presently used by hiredis to manage
267
+ * SSL connections. */
268
+ void *privctx;
269
+
270
+ /* An optional RESP3 PUSH handler */
271
+ redisPushFn *push_cb;
272
+ } redisContext;
273
+
274
+ redisContext *redisConnectWithOptions(const redisOptions *options);
275
+ redisContext *redisConnect(const char *ip, int port);
276
+ redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
277
+ redisContext *redisConnectNonBlock(const char *ip, int port);
278
+ redisContext *redisConnectBindNonBlock(const char *ip, int port,
279
+ const char *source_addr);
280
+ redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
281
+ const char *source_addr);
282
+ redisContext *redisConnectUnix(const char *path);
283
+ redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
284
+ redisContext *redisConnectUnixNonBlock(const char *path);
285
+ redisContext *redisConnectFd(redisFD fd);
286
+
287
+ /**
288
+ * Reconnect the given context using the saved information.
289
+ *
290
+ * This re-uses the exact same connect options as in the initial connection.
291
+ * host, ip (or path), timeout and bind address are reused,
292
+ * flags are used unmodified from the existing context.
293
+ *
294
+ * Returns REDIS_OK on successful connect or REDIS_ERR otherwise.
295
+ */
296
+ int redisReconnect(redisContext *c);
297
+
298
+ redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn);
299
+ int redisSetTimeout(redisContext *c, const struct timeval tv);
300
+ int redisEnableKeepAlive(redisContext *c);
301
+ void redisFree(redisContext *c);
302
+ redisFD redisFreeKeepFd(redisContext *c);
303
+ int redisBufferRead(redisContext *c);
304
+ int redisBufferWrite(redisContext *c, int *done);
305
+
306
+ /* In a blocking context, this function first checks if there are unconsumed
307
+ * replies to return and returns one if so. Otherwise, it flushes the output
308
+ * buffer to the socket and reads until it has a reply. In a non-blocking
309
+ * context, it will return unconsumed replies until there are no more. */
310
+ int redisGetReply(redisContext *c, void **reply);
311
+ int redisGetReplyFromReader(redisContext *c, void **reply);
312
+
313
+ /* Write a formatted command to the output buffer. Use these functions in blocking mode
314
+ * to get a pipeline of commands. */
315
+ int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
316
+
317
+ /* Write a command to the output buffer. Use these functions in blocking mode
318
+ * to get a pipeline of commands. */
319
+ int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
320
+ int redisAppendCommand(redisContext *c, const char *format, ...);
321
+ int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
322
+
323
+ /* Issue a command to Redis. In a blocking context, it is identical to calling
324
+ * redisAppendCommand, followed by redisGetReply. The function will return
325
+ * NULL if there was an error in performing the request, otherwise it will
326
+ * return the reply. In a non-blocking context, it is identical to calling
327
+ * only redisAppendCommand and will always return NULL. */
328
+ void *redisvCommand(redisContext *c, const char *format, va_list ap);
329
+ void *redisCommand(redisContext *c, const char *format, ...);
330
+ void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
331
+
332
+ #ifdef __cplusplus
333
+ }
334
+ #endif
335
+
336
+ #endif
@@ -0,0 +1,127 @@
1
+
2
+ /*
3
+ * Copyright (c) 2019, Redis Labs
4
+ *
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ * * Neither the name of Redis nor the names of its contributors may be used
16
+ * to endorse or promote products derived from this software without
17
+ * specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+
32
+ #ifndef __HIREDIS_SSL_H
33
+ #define __HIREDIS_SSL_H
34
+
35
+ #ifdef __cplusplus
36
+ extern "C" {
37
+ #endif
38
+
39
+ /* This is the underlying struct for SSL in ssl.h, which is not included to
40
+ * keep build dependencies short here.
41
+ */
42
+ struct ssl_st;
43
+
44
+ /* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly
45
+ * calling OpenSSL.
46
+ */
47
+ typedef struct redisSSLContext redisSSLContext;
48
+
49
+ /**
50
+ * Initialization errors that redisCreateSSLContext() may return.
51
+ */
52
+
53
+ typedef enum {
54
+ REDIS_SSL_CTX_NONE = 0, /* No Error */
55
+ REDIS_SSL_CTX_CREATE_FAILED, /* Failed to create OpenSSL SSL_CTX */
56
+ REDIS_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */
57
+ REDIS_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */
58
+ REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */
59
+ REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED /* Failed to load private key */
60
+ } redisSSLContextError;
61
+
62
+ /**
63
+ * Return the error message corresponding with the specified error code.
64
+ */
65
+
66
+ const char *redisSSLContextGetError(redisSSLContextError error);
67
+
68
+ /**
69
+ * Helper function to initialize the OpenSSL library.
70
+ *
71
+ * OpenSSL requires one-time initialization before it can be used. Callers should
72
+ * call this function only once, and only if OpenSSL is not directly initialized
73
+ * elsewhere.
74
+ */
75
+ int redisInitOpenSSL(void);
76
+
77
+ /**
78
+ * Helper function to initialize an OpenSSL context that can be used
79
+ * to initiate SSL connections.
80
+ *
81
+ * cacert_filename is an optional name of a CA certificate/bundle file to load
82
+ * and use for validation.
83
+ *
84
+ * capath is an optional directory path where trusted CA certificate files are
85
+ * stored in an OpenSSL-compatible structure.
86
+ *
87
+ * cert_filename and private_key_filename are optional names of a client side
88
+ * certificate and private key files to use for authentication. They need to
89
+ * be both specified or omitted.
90
+ *
91
+ * server_name is an optional and will be used as a server name indication
92
+ * (SNI) TLS extension.
93
+ *
94
+ * If error is non-null, it will be populated in case the context creation fails
95
+ * (returning a NULL).
96
+ */
97
+
98
+ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath,
99
+ const char *cert_filename, const char *private_key_filename,
100
+ const char *server_name, redisSSLContextError *error);
101
+
102
+ /**
103
+ * Free a previously created OpenSSL context.
104
+ */
105
+ void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx);
106
+
107
+ /**
108
+ * Initiate SSL on an existing redisContext.
109
+ *
110
+ * This is similar to redisInitiateSSL() but does not require the caller
111
+ * to directly interact with OpenSSL, and instead uses a redisSSLContext
112
+ * previously created using redisCreateSSLContext().
113
+ */
114
+
115
+ int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx);
116
+
117
+ /**
118
+ * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object.
119
+ */
120
+
121
+ int redisInitiateSSL(redisContext *c, struct ssl_st *ssl);
122
+
123
+ #ifdef __cplusplus
124
+ }
125
+ #endif
126
+
127
+ #endif /* __HIREDIS_SSL_H */