Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
e7a3d3d1
Unverified
Commit
e7a3d3d1
authored
Jun 06, 2023
by
Yossi Gottlieb
Committed by
GitHub
Jun 06, 2023
Browse files
Merge pull request #12254 from yossigo/hiredis-refresh
Refresh deps/hiredis to latest (unreleased) version.
parents
0bd1a3a4
032bb2a2
Changes
42
Show whitespace changes
Inline
Side-by-side
deps/hiredis/examples/example-poll.c
0 → 100644
View file @
e7a3d3d1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <async.h>
#include <adapters/poll.h>
/* Put in the global scope, so that loop can be explicitly stopped */
static
int
exit_loop
=
0
;
void
getCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
return
;
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect
(
c
);
}
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
exit_loop
=
1
;
return
;
}
printf
(
"Connected...
\n
"
);
}
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
exit_loop
=
1
;
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Disconnected...
\n
"
);
}
int
main
(
int
argc
,
char
**
argv
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
err
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
1
;
}
redisPollAttach
(
c
);
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
while
(
!
exit_loop
)
{
redisPollTick
(
c
,
0
.
1
);
}
return
0
;
}
deps/hiredis/examples/example-redismoduleapi.c
0 → 100644
View file @
e7a3d3d1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/redismoduleapi.h>
void
debugCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
(
void
)
privdata
;
//unused
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
/* The DEBUG SLEEP command will almost always fail, because we have set a 1 second timeout */
printf
(
"`DEBUG SLEEP` error: %s
\n
"
,
c
->
errstr
?
c
->
errstr
:
"unknown error"
);
return
;
}
/* Disconnect after receiving the reply of DEBUG SLEEP (which will not)*/
redisAsyncDisconnect
(
c
);
}
void
getCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
if
(
c
->
errstr
)
{
printf
(
"errstr: %s
\n
"
,
c
->
errstr
);
}
return
;
}
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* start another request that demonstrate timeout */
redisAsyncCommand
(
c
,
debugCallback
,
NULL
,
"DEBUG SLEEP %f"
,
1
.
5
);
}
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Connected...
\n
"
);
}
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Disconnected...
\n
"
);
}
/*
* This example requires Redis 7.0 or above.
*
* 1- Compile this file as a shared library. Directory of "redismodule.h" must
* be in the include path.
* gcc -fPIC -shared -I../../redis/src/ -I.. example-redismoduleapi.c -o example-redismoduleapi.so
*
* 2- Load module:
* redis-server --loadmodule ./example-redismoduleapi.so value
*/
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
int
ret
=
RedisModule_Init
(
ctx
,
"example-redismoduleapi"
,
1
,
REDISMODULE_APIVER_1
);
if
(
ret
!=
REDISMODULE_OK
)
{
printf
(
"error module init
\n
"
);
return
REDISMODULE_ERR
;
}
if
(
redisModuleCompatibilityCheck
()
!=
REDIS_OK
)
{
printf
(
"Redis 7.0 or above is required!
\n
"
);
return
REDISMODULE_ERR
;
}
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
err
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
1
;
}
size_t
len
;
const
char
*
val
=
RedisModule_StringPtrLen
(
argv
[
argc
-
1
],
&
len
);
RedisModuleCtx
*
module_ctx
=
RedisModule_GetDetachedThreadSafeContext
(
ctx
);
redisModuleAttach
(
c
,
module_ctx
);
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncSetTimeout
(
c
,
(
struct
timeval
){
.
tv_sec
=
1
,
.
tv_usec
=
0
});
/*
In this demo, we first `set key`, then `get key` to demonstrate the basic usage of the adapter.
Then in `getCallback`, we start a `debug sleep` command to create 1.5 second long request.
Because we have set a 1 second timeout to the connection, the command will always fail with a
timeout error, which is shown in the `debugCallback`.
*/
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
val
,
len
);
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
return
0
;
}
deps/hiredis/examples/example-ssl.c
View file @
e7a3d3d1
...
...
@@ -12,7 +12,7 @@
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
int
j
;
redisSSLContext
*
ssl
;
redisSSLContextError
ssl_error
;
redisSSLContextError
ssl_error
=
REDIS_SSL_CTX_NONE
;
redisContext
*
c
;
redisReply
*
reply
;
if
(
argc
<
4
)
{
...
...
@@ -27,9 +27,8 @@ int main(int argc, char **argv) {
redisInitOpenSSL
();
ssl
=
redisCreateSSLContext
(
ca
,
NULL
,
cert
,
key
,
NULL
,
&
ssl_error
);
if
(
!
ssl
)
{
printf
(
"SSL Context error: %s
\n
"
,
redisSSLContextGetError
(
ssl_error
));
if
(
!
ssl
||
ssl_error
!=
REDIS_SSL_CTX_NONE
)
{
printf
(
"SSL Context error: %s
\n
"
,
redisSSLContextGetError
(
ssl_error
));
exit
(
1
);
}
...
...
deps/hiredis/examples/example.c
View file @
e7a3d3d1
...
...
@@ -7,6 +7,54 @@
#include <winsock2.h>
/* For struct timeval */
#endif
static
void
example_argv_command
(
redisContext
*
c
,
size_t
n
)
{
char
**
argv
,
tmp
[
42
];
size_t
*
argvlen
;
redisReply
*
reply
;
/* We're allocating two additional elements for command and key */
argv
=
malloc
(
sizeof
(
*
argv
)
*
(
2
+
n
));
argvlen
=
malloc
(
sizeof
(
*
argvlen
)
*
(
2
+
n
));
/* First the command */
argv
[
0
]
=
(
char
*
)
"RPUSH"
;
argvlen
[
0
]
=
sizeof
(
"RPUSH"
)
-
1
;
/* Now our key */
argv
[
1
]
=
(
char
*
)
"argvlist"
;
argvlen
[
1
]
=
sizeof
(
"argvlist"
)
-
1
;
/* Now add the entries we wish to add to the list */
for
(
size_t
i
=
2
;
i
<
(
n
+
2
);
i
++
)
{
argvlen
[
i
]
=
snprintf
(
tmp
,
sizeof
(
tmp
),
"argv-element-%zu"
,
i
-
2
);
argv
[
i
]
=
strdup
(
tmp
);
}
/* Execute the command using redisCommandArgv. We're sending the arguments with
* two explicit arrays. One for each argument's string, and the other for its
* length. */
reply
=
redisCommandArgv
(
c
,
n
+
2
,
(
const
char
**
)
argv
,
(
const
size_t
*
)
argvlen
);
if
(
reply
==
NULL
||
c
->
err
)
{
fprintf
(
stderr
,
"Error: Couldn't execute redisCommandArgv
\n
"
);
exit
(
1
);
}
if
(
reply
->
type
==
REDIS_REPLY_INTEGER
)
{
printf
(
"%s reply: %lld
\n
"
,
argv
[
0
],
reply
->
integer
);
}
freeReplyObject
(
reply
);
/* Clean up */
for
(
size_t
i
=
2
;
i
<
(
n
+
2
);
i
++
)
{
free
(
argv
[
i
]);
}
free
(
argv
);
free
(
argvlen
);
}
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
int
j
,
isunix
=
0
;
redisContext
*
c
;
...
...
@@ -87,6 +135,9 @@ int main(int argc, char **argv) {
}
freeReplyObject
(
reply
);
/* See function for an example of redisCommandArgv */
example_argv_command
(
c
,
10
);
/* Disconnects and frees the context */
redisFree
(
c
);
...
...
deps/hiredis/fuzzing/format_command_fuzzer.c
View file @
e7a3d3d1
...
...
@@ -48,10 +48,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
memcpy
(
new_str
,
data
,
size
);
new_str
[
size
]
=
'\0'
;
redisFormatCommand
(
&
cmd
,
new_str
);
if
(
cmd
!=
NULL
)
if
(
redisFormatCommand
(
&
cmd
,
new_str
)
!=
-
1
)
hi_free
(
cmd
);
free
(
new_str
);
return
0
;
}
deps/hiredis/hiredis-config.cmake.in
View file @
e7a3d3d1
...
...
@@ -2,11 +2,11 @@
set_and_check(hiredis_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
IF (NOT TARGET hiredis::hiredis)
IF (NOT TARGET hiredis::
@
hiredis
_export_name@
)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis-targets.cmake)
ENDIF()
SET(hiredis_LIBRARIES hiredis::hiredis)
SET(hiredis_LIBRARIES hiredis::
@
hiredis
_export_name@
)
SET(hiredis_INCLUDE_DIRS ${hiredis_INCLUDEDIR})
check_required_components(hiredis)
...
...
deps/hiredis/hiredis.c
View file @
e7a3d3d1
...
...
@@ -48,6 +48,7 @@ extern int redisContextUpdateConnectTimeout(redisContext *c, const struct timeva
extern
int
redisContextUpdateCommandTimeout
(
redisContext
*
c
,
const
struct
timeval
*
timeout
);
static
redisContextFuncs
redisContextDefaultFuncs
=
{
.
close
=
redisNetClose
,
.
free_privctx
=
NULL
,
.
async_read
=
redisAsyncRead
,
.
async_write
=
redisAsyncWrite
,
...
...
@@ -221,6 +222,9 @@ static void *createIntegerObject(const redisReadTask *task, long long value) {
static
void
*
createDoubleObject
(
const
redisReadTask
*
task
,
double
value
,
char
*
str
,
size_t
len
)
{
redisReply
*
r
,
*
parent
;
if
(
len
==
SIZE_MAX
)
// Prevents hi_malloc(0) if len equals to SIZE_MAX
return
NULL
;
r
=
createReplyObject
(
REDIS_REPLY_DOUBLE
);
if
(
r
==
NULL
)
return
NULL
;
...
...
@@ -399,6 +403,11 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
/* Copy va_list before consuming with va_arg */
va_copy
(
_cpy
,
ap
);
/* Make sure we have more characters otherwise strchr() accepts
* '\0' as an integer specifier. This is checked after above
* va_copy() to avoid UB in fmt_invalid's call to va_end(). */
if
(
*
_p
==
'\0'
)
goto
fmt_invalid
;
/* Integer conversion (without modifiers) */
if
(
strchr
(
intfmts
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
int
);
...
...
@@ -477,6 +486,8 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
touched
=
1
;
c
++
;
if
(
*
c
==
'\0'
)
break
;
}
c
++
;
}
...
...
@@ -719,7 +730,10 @@ static redisContext *redisContextInit(void) {
void
redisFree
(
redisContext
*
c
)
{
if
(
c
==
NULL
)
return
;
redisNetClose
(
c
);
if
(
c
->
funcs
&&
c
->
funcs
->
close
)
{
c
->
funcs
->
close
(
c
);
}
hi_sdsfree
(
c
->
obuf
);
redisReaderFree
(
c
->
reader
);
...
...
@@ -733,7 +747,7 @@ void redisFree(redisContext *c) {
if
(
c
->
privdata
&&
c
->
free_privdata
)
c
->
free_privdata
(
c
->
privdata
);
if
(
c
->
funcs
->
free_privctx
)
if
(
c
->
funcs
&&
c
->
funcs
->
free_privctx
)
c
->
funcs
->
free_privctx
(
c
->
privctx
);
memset
(
c
,
0xff
,
sizeof
(
*
c
));
...
...
@@ -756,7 +770,9 @@ int redisReconnect(redisContext *c) {
c
->
privctx
=
NULL
;
}
redisNetClose
(
c
);
if
(
c
->
funcs
&&
c
->
funcs
->
close
)
{
c
->
funcs
->
close
(
c
);
}
hi_sdsfree
(
c
->
obuf
);
redisReaderFree
(
c
->
reader
);
...
...
@@ -806,6 +822,12 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
if
(
options
->
options
&
REDIS_OPT_NOAUTOFREEREPLIES
)
{
c
->
flags
|=
REDIS_NO_AUTO_FREE_REPLIES
;
}
if
(
options
->
options
&
REDIS_OPT_PREFER_IPV4
)
{
c
->
flags
|=
REDIS_PREFER_IPV4
;
}
if
(
options
->
options
&
REDIS_OPT_PREFER_IPV6
)
{
c
->
flags
|=
REDIS_PREFER_IPV6
;
}
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
* as a default unless specifically flagged that we don't want one. */
...
...
@@ -838,7 +860,9 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
return
NULL
;
}
if
(
options
->
command_timeout
!=
NULL
&&
(
c
->
flags
&
REDIS_BLOCK
)
&&
c
->
fd
!=
REDIS_INVALID_FD
)
{
if
(
c
->
err
==
0
&&
c
->
fd
!=
REDIS_INVALID_FD
&&
options
->
command_timeout
!=
NULL
&&
(
c
->
flags
&
REDIS_BLOCK
))
{
redisContextSetTimeout
(
c
,
*
options
->
command_timeout
);
}
...
...
@@ -920,11 +944,18 @@ int redisSetTimeout(redisContext *c, const struct timeval tv) {
return
REDIS_ERR
;
}
int
redisEnableKeepAliveWithInterval
(
redisContext
*
c
,
int
interval
)
{
return
redisKeepAlive
(
c
,
interval
);
}
/* Enable connection KeepAlive. */
int
redisEnableKeepAlive
(
redisContext
*
c
)
{
if
(
redisKeepAlive
(
c
,
REDIS_KEEPALIVE_INTERVAL
)
!=
REDIS_OK
)
return
REDIS_ERR
;
return
REDIS_OK
;
return
redisKeepAlive
(
c
,
REDIS_KEEPALIVE_INTERVAL
);
}
/* Set the socket option TCP_USER_TIMEOUT. */
int
redisSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
)
{
return
redisContextSetTcpUserTimeout
(
c
,
timeout
);
}
/* Set a user provided RESP3 PUSH handler and return any old one set. */
...
...
@@ -964,8 +995,8 @@ int redisBufferRead(redisContext *c) {
* successfully written to the socket. When the buffer is empty after the
* write operation, "done" is set to 1 (if given).
*
* Returns REDIS_ERR if an error occurred
try
in
g
t
o writ
e
a
nd
sets
* c->
errstr to hold the approp
ri
a
te
error string
.
* Returns REDIS_ERR if an
unrecoverable
error occurred in t
h
e
u
nd
erlying
* c->
funcs->w
rite
function
.
*/
int
redisBufferWrite
(
redisContext
*
c
,
int
*
done
)
{
...
...
deps/hiredis/hiredis.h
View file @
e7a3d3d1
...
...
@@ -46,9 +46,9 @@ typedef long long ssize_t;
#include "alloc.h"
/* for allocation wrappers */
#define HIREDIS_MAJOR 1
#define HIREDIS_MINOR
0
#define HIREDIS_PATCH
3
#define HIREDIS_SONAME 1.
0.3
-dev
#define HIREDIS_MINOR
1
#define HIREDIS_PATCH
1
#define HIREDIS_SONAME 1.
1.1
-dev
/* Connection type can be blocking or non-blocking and is set in the
* least significant bit of the flags field in redisContext. */
...
...
@@ -92,6 +92,11 @@ typedef long long ssize_t;
/* Flag that indicates the user does not want replies to be automatically freed */
#define REDIS_NO_AUTO_FREE_REPLIES 0x400
/* Flags to prefer IPv6 or IPv4 when doing DNS lookup. (If both are set,
* AF_UNSPEC is used.) */
#define REDIS_PREFER_IPV4 0x800
#define REDIS_PREFER_IPV6 0x1000
#define REDIS_KEEPALIVE_INTERVAL 15
/* seconds */
/* number of times we retry to connect in the case of EADDRNOTAVAIL and
...
...
@@ -149,20 +154,17 @@ struct redisSsl;
#define REDIS_OPT_NONBLOCK 0x01
#define REDIS_OPT_REUSEADDR 0x02
/**
* Don't automatically free the async object on a connection failure,
* or other implicit conditions. Only free on an explicit call to disconnect() or free()
*/
#define REDIS_OPT_NOAUTOFREE 0x04
/* Don't automatically intercept and free RESP3 PUSH replies. */
#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
/**
* Don't automatically free replies
*/
#define REDIS_OPT_NOAUTOFREEREPLIES 0x10
#define REDIS_OPT_NOAUTOFREE 0x04
/* Don't automatically free the async
* object on a connection failure, or
* other implicit conditions. Only free
* on an explicit call to disconnect()
* or free() */
#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
/* Don't automatically intercept and
* free RESP3 PUSH replies. */
#define REDIS_OPT_NOAUTOFREEREPLIES 0x10
/* Don't automatically free replies. */
#define REDIS_OPT_PREFER_IPV4 0x20
/* Prefer IPv4 in DNS lookups. */
#define REDIS_OPT_PREFER_IPV6 0x40
/* Prefer IPv6 in DNS lookups. */
#define REDIS_OPT_PREFER_IP_UNSPEC (REDIS_OPT_PREFER_IPV4 | REDIS_OPT_PREFER_IPV6)
/* In Unix systems a file descriptor is a regular signed int, with -1
* representing an invalid descriptor. In Windows it is a SOCKET
...
...
@@ -220,27 +222,37 @@ typedef struct {
/**
* Helper macros to initialize options to their specified fields.
*/
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_)
do {
\
(opts)->type = REDIS_CONN_TCP; \
(opts)->endpoint.tcp.ip = ip_; \
(opts)->endpoint.tcp.port = port_;
(opts)->endpoint.tcp.port = port_; \
} while(0)
#define REDIS_OPTIONS_SET_UNIX(opts, path) \
#define REDIS_OPTIONS_SET_UNIX(opts, path)
do {
\
(opts)->type = REDIS_CONN_UNIX; \
(opts)->endpoint.unix_socket = path;
(opts)->endpoint.unix_socket = path; \
} while(0)
#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \
#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor)
do {
\
(opts)->privdata = data; \
(opts)->free_privdata = dtor; \
} while(0)
typedef
struct
redisContextFuncs
{
void
(
*
close
)(
struct
redisContext
*
);
void
(
*
free_privctx
)(
void
*
);
void
(
*
async_read
)(
struct
redisAsyncContext
*
);
void
(
*
async_write
)(
struct
redisAsyncContext
*
);
/* Read/Write data to the underlying communication stream, returning the
* number of bytes read/written. In the event of an unrecoverable error
* these functions shall return a value < 0. In the event of a
* recoverable error, they should return 0. */
ssize_t
(
*
read
)(
struct
redisContext
*
,
char
*
,
size_t
);
ssize_t
(
*
write
)(
struct
redisContext
*
);
}
redisContextFuncs
;
/* Context for a connection to Redis */
typedef
struct
redisContext
{
const
redisContextFuncs
*
funcs
;
/* Function table */
...
...
@@ -310,6 +322,8 @@ int redisReconnect(redisContext *c);
redisPushFn
*
redisSetPushCallback
(
redisContext
*
c
,
redisPushFn
*
fn
);
int
redisSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
int
redisEnableKeepAlive
(
redisContext
*
c
);
int
redisEnableKeepAliveWithInterval
(
redisContext
*
c
,
int
interval
);
int
redisSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
);
void
redisFree
(
redisContext
*
c
);
redisFD
redisFreeKeepFd
(
redisContext
*
c
);
int
redisBufferRead
(
redisContext
*
c
);
...
...
deps/hiredis/hiredis.pc.in
View file @
e7a3d3d1
...
...
@@ -9,4 +9,4 @@ Name: hiredis
Description: Minimalistic C client library for Redis.
Version: @PROJECT_VERSION@
Libs: -L${libdir} -lhiredis
Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64
Cflags: -I${pkgincludedir}
-I${includedir}
-D_FILE_OFFSET_BITS=64
deps/hiredis/hiredis_ssl-config.cmake.in
View file @
e7a3d3d1
...
...
@@ -2,6 +2,9 @@
set_and_check(hiredis_ssl_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
include(CMakeFindDependencyMacro)
find_dependency(OpenSSL)
IF (NOT TARGET hiredis::hiredis_ssl)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis_ssl-targets.cmake)
ENDIF()
...
...
deps/hiredis/hiredis_ssl.h
View file @
e7a3d3d1
...
...
@@ -56,11 +56,33 @@ typedef enum {
REDIS_SSL_CTX_CERT_KEY_REQUIRED
,
/* Client cert and key must both be specified or skipped */
REDIS_SSL_CTX_CA_CERT_LOAD_FAILED
,
/* Failed to load CA Certificate or CA Path */
REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED
,
/* Failed to load client certificate */
REDIS_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED
,
/* Failed to set client default certificate directory */
REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED
,
/* Failed to load private key */
REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED
,
/* Failed to open system certificate store */
REDIS_SSL_CTX_OS_CERT_ADD_FAILED
/* Failed to add CA certificates obtained from system to the SSL context */
}
redisSSLContextError
;
/* Constants that mirror OpenSSL's verify modes. By default,
* REDIS_SSL_VERIFY_PEER is used with redisCreateSSLContext().
* Some Redis clients disable peer verification if there are no
* certificates specified.
*/
#define REDIS_SSL_VERIFY_NONE 0x00
#define REDIS_SSL_VERIFY_PEER 0x01
#define REDIS_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
#define REDIS_SSL_VERIFY_CLIENT_ONCE 0x04
#define REDIS_SSL_VERIFY_POST_HANDSHAKE 0x08
/* Options to create an OpenSSL context. */
typedef
struct
{
const
char
*
cacert_filename
;
const
char
*
capath
;
const
char
*
cert_filename
;
const
char
*
private_key_filename
;
const
char
*
server_name
;
int
verify_mode
;
}
redisSSLOptions
;
/**
* Return the error message corresponding with the specified error code.
*/
...
...
@@ -101,6 +123,18 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
const
char
*
cert_filename
,
const
char
*
private_key_filename
,
const
char
*
server_name
,
redisSSLContextError
*
error
);
/**
* Helper function to initialize an OpenSSL context that can be used
* to initiate SSL connections. This is a more extensible version of redisCreateSSLContext().
*
* options contains a structure of SSL options to use.
*
* If error is non-null, it will be populated in case the context creation fails
* (returning a NULL).
*/
redisSSLContext
*
redisCreateSSLContextWithOptions
(
redisSSLOptions
*
options
,
redisSSLContextError
*
error
);
/**
* Free a previously created OpenSSL context.
*/
...
...
deps/hiredis/hiredis_ssl.pc.in
View file @
e7a3d3d1
prefix=@CMAKE_INSTALL_PREFIX@
install_libdir=@CMAKE_INSTALL_LIBDIR@
exec_prefix=${prefix}
libdir=${exec_prefix}/
lib
libdir=${exec_prefix}/
${install_libdir}
includedir=${prefix}/include
pkgincludedir=${includedir}/hiredis
...
...
deps/hiredis/net.c
View file @
e7a3d3d1
...
...
@@ -50,6 +50,8 @@
/* Defined in hiredis.c */
void
__redisSetError
(
redisContext
*
c
,
int
type
,
const
char
*
str
);
int
redisContextUpdateCommandTimeout
(
redisContext
*
c
,
const
struct
timeval
*
timeout
);
void
redisNetClose
(
redisContext
*
c
)
{
if
(
c
&&
c
->
fd
!=
REDIS_INVALID_FD
)
{
close
(
c
->
fd
);
...
...
@@ -68,7 +70,7 @@ ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) {
__redisSetError
(
c
,
REDIS_ERR_TIMEOUT
,
"recv timeout"
);
return
-
1
;
}
else
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetError
(
c
,
REDIS_ERR_IO
,
strerror
(
errno
)
);
return
-
1
;
}
}
else
if
(
nread
==
0
)
{
...
...
@@ -80,15 +82,19 @@ ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) {
}
ssize_t
redisNetWrite
(
redisContext
*
c
)
{
ssize_t
nwritten
=
send
(
c
->
fd
,
c
->
obuf
,
hi_sdslen
(
c
->
obuf
),
0
);
ssize_t
nwritten
;
nwritten
=
send
(
c
->
fd
,
c
->
obuf
,
hi_sdslen
(
c
->
obuf
),
0
);
if
(
nwritten
<
0
)
{
if
((
errno
==
EWOULDBLOCK
&&
!
(
c
->
flags
&
REDIS_BLOCK
))
||
(
errno
==
EINTR
))
{
/* Try again later */
/* Try again */
return
0
;
}
else
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetError
(
c
,
REDIS_ERR_IO
,
strerror
(
errno
)
);
return
-
1
;
}
}
return
nwritten
;
}
...
...
@@ -166,6 +172,7 @@ int redisKeepAlive(redisContext *c, int interval) {
int
val
=
1
;
redisFD
fd
=
c
->
fd
;
#ifndef _WIN32
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_KEEPALIVE
,
&
val
,
sizeof
(
val
))
==
-
1
){
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
strerror
(
errno
));
return
REDIS_ERR
;
...
...
@@ -199,7 +206,15 @@ int redisKeepAlive(redisContext *c, int interval) {
}
#endif
#endif
#else
int
res
;
res
=
win32_redisKeepAlive
(
fd
,
interval
*
1000
);
if
(
res
!=
0
)
{
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
strerror
(
res
));
return
REDIS_ERR
;
}
#endif
return
REDIS_OK
;
}
...
...
@@ -213,6 +228,22 @@ int redisSetTcpNoDelay(redisContext *c) {
return
REDIS_OK
;
}
int
redisContextSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
)
{
int
res
;
#ifdef TCP_USER_TIMEOUT
res
=
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_USER_TIMEOUT
,
&
timeout
,
sizeof
(
timeout
));
#else
res
=
-
1
;
(
void
)
timeout
;
#endif
if
(
res
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"setsockopt(TCP_USER_TIMEOUT)"
);
redisNetClose
(
c
);
return
REDIS_ERR
;
}
return
REDIS_OK
;
}
#define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
static
int
redisContextTimeoutMsec
(
redisContext
*
c
,
long
*
result
)
...
...
@@ -223,6 +254,7 @@ static int redisContextTimeoutMsec(redisContext *c, long *result)
/* Only use timeout when not NULL. */
if
(
timeout
!=
NULL
)
{
if
(
timeout
->
tv_usec
>
1000000
||
timeout
->
tv_sec
>
__MAX_MSEC
)
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
"Invalid timeout specified"
);
*
result
=
msec
;
return
REDIS_ERR
;
}
...
...
@@ -277,12 +309,28 @@ int redisCheckConnectDone(redisContext *c, int *completed) {
*
completed
=
1
;
return
REDIS_OK
;
}
switch
(
errno
)
{
int
error
=
errno
;
if
(
error
==
EINPROGRESS
)
{
/* must check error to see if connect failed. Get the socket error */
int
fail
,
so_error
;
socklen_t
optlen
=
sizeof
(
so_error
);
fail
=
getsockopt
(
c
->
fd
,
SOL_SOCKET
,
SO_ERROR
,
&
so_error
,
&
optlen
);
if
(
fail
==
0
)
{
if
(
so_error
==
0
)
{
/* Socket is connected! */
*
completed
=
1
;
return
REDIS_OK
;
}
/* connection error; */
errno
=
so_error
;
error
=
so_error
;
}
}
switch
(
error
)
{
case
EISCONN
:
*
completed
=
1
;
return
REDIS_OK
;
case
EALREADY
:
case
EINPROGRESS
:
case
EWOULDBLOCK
:
*
completed
=
0
;
return
REDIS_OK
;
...
...
@@ -317,6 +365,10 @@ int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
const
void
*
to_ptr
=
&
tv
;
size_t
to_sz
=
sizeof
(
tv
);
if
(
redisContextUpdateCommandTimeout
(
c
,
&
tv
)
!=
REDIS_OK
)
{
__redisSetError
(
c
,
REDIS_ERR_OOM
,
"Out of memory"
);
return
REDIS_ERR
;
}
if
(
setsockopt
(
c
->
fd
,
SOL_SOCKET
,
SO_RCVTIMEO
,
to_ptr
,
to_sz
)
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"setsockopt(SO_RCVTIMEO)"
);
return
REDIS_ERR
;
...
...
@@ -400,7 +452,6 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
}
if
(
redisContextTimeoutMsec
(
c
,
&
timeout_msec
)
!=
REDIS_OK
)
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
"Invalid timeout specified"
);
goto
error
;
}
...
...
@@ -417,17 +468,25 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
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
IP
v
6
if both addresses are available and there is IPv6
* connectivity. */
if
((
rv
=
getaddrinfo
(
c
->
tcp
.
host
,
_port
,
&
hints
,
&
servinfo
))
!=
0
)
{
/*
DNS lookup. To use dual stack, set both flags to prefer both IPv4 and
*
IPv6. By default, for historical reasons, we try IPv4 first and then we
*
try IPv6 only if no IPv4 address was found. */
if
(
c
->
flags
&
REDIS_PREFER_
IP
V
6
&&
c
->
flags
&
REDIS_PREFER_IPV4
)
hints
.
ai_family
=
AF_UNSPEC
;
else
if
(
c
->
flags
&
REDIS_PREFER_IPV6
)
hints
.
ai_family
=
AF_INET6
;
if
((
rv
=
getaddrinfo
(
addr
,
_port
,
&
hints
,
&
servinfo
))
!=
0
)
{
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
gai_strerror
(
rv
));
return
REDIS_ERR
;
else
hints
.
ai_family
=
AF_INET
;
rv
=
getaddrinfo
(
c
->
tcp
.
host
,
_port
,
&
hints
,
&
servinfo
);
if
(
rv
!=
0
&&
hints
.
ai_family
!=
AF_UNSPEC
)
{
/* Try again with the other IP version. */
hints
.
ai_family
=
(
hints
.
ai_family
==
AF_INET
)
?
AF_INET6
:
AF_INET
;
rv
=
getaddrinfo
(
c
->
tcp
.
host
,
_port
,
&
hints
,
&
servinfo
);
}
if
(
rv
!=
0
)
{
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
gai_strerror
(
rv
));
return
REDIS_ERR
;
}
for
(
p
=
servinfo
;
p
!=
NULL
;
p
=
p
->
ai_next
)
{
addrretry:
...
...
deps/hiredis/net.h
View file @
e7a3d3d1
...
...
@@ -52,5 +52,6 @@ int redisKeepAlive(redisContext *c, int interval);
int
redisCheckConnectDone
(
redisContext
*
c
,
int
*
completed
);
int
redisSetTcpNoDelay
(
redisContext
*
c
);
int
redisContextSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
);
#endif
deps/hiredis/read.c
View file @
e7a3d3d1
...
...
@@ -303,11 +303,14 @@ static int processLineItem(redisReader *r) {
d
=
INFINITY
;
/* Positive infinite. */
}
else
if
(
len
==
4
&&
strcasecmp
(
buf
,
"-inf"
)
==
0
)
{
d
=
-
INFINITY
;
/* Negative infinite. */
}
else
if
((
len
==
3
&&
strcasecmp
(
buf
,
"nan"
)
==
0
)
||
(
len
==
4
&&
strcasecmp
(
buf
,
"-nan"
)
==
0
))
{
d
=
NAN
;
/* nan. */
}
else
{
d
=
strtod
((
char
*
)
buf
,
&
eptr
);
/* RESP3 only allows "inf", "-inf", and finite values, while
* strtod() allows other variations on infinity,
NaN,
* etc. We explicity handle our two allowed infinite cases
* strtod() allows other variations on infinity,
* etc. We explicity handle our two allowed infinite cases
and NaN
* above, so strtod() should only result in finite values. */
if
(
buf
[
0
]
==
'\0'
||
eptr
!=
&
buf
[
len
]
||
!
isfinite
(
d
))
{
__redisReaderSetError
(
r
,
REDIS_ERR_PROTOCOL
,
...
...
@@ -374,7 +377,7 @@ static int processLineItem(redisReader *r) {
if
(
r
->
fn
&&
r
->
fn
->
createString
)
obj
=
r
->
fn
->
createString
(
cur
,
p
,
len
);
else
obj
=
(
void
*
)(
size
_t
)(
cur
->
type
);
obj
=
(
void
*
)(
uintptr
_t
)(
cur
->
type
);
}
if
(
obj
==
NULL
)
{
...
...
@@ -439,7 +442,7 @@ static int processBulkItem(redisReader *r) {
if
(
r
->
fn
&&
r
->
fn
->
createString
)
obj
=
r
->
fn
->
createString
(
cur
,
s
+
2
,
len
);
else
obj
=
(
void
*
)(
long
)
cur
->
type
;
obj
=
(
void
*
)(
uintptr_t
)
cur
->
type
;
success
=
1
;
}
}
...
...
@@ -536,7 +539,7 @@ static int processAggregateItem(redisReader *r) {
if
(
r
->
fn
&&
r
->
fn
->
createArray
)
obj
=
r
->
fn
->
createArray
(
cur
,
elements
);
else
obj
=
(
void
*
)(
long
)
cur
->
type
;
obj
=
(
void
*
)(
uintptr_t
)
cur
->
type
;
if
(
obj
==
NULL
)
{
__redisReaderSetErrorOOM
(
r
);
...
...
deps/hiredis/sds.c
View file @
e7a3d3d1
...
...
@@ -90,6 +90,7 @@ hisds hi_sdsnewlen(const void *init, size_t initlen) {
int
hdrlen
=
hi_sdsHdrSize
(
type
);
unsigned
char
*
fp
;
/* flags pointer. */
if
(
hdrlen
+
initlen
+
1
<=
initlen
)
return
NULL
;
/* Catch size_t overflow */
sh
=
hi_s_malloc
(
hdrlen
+
initlen
+
1
);
if
(
sh
==
NULL
)
return
NULL
;
if
(
!
init
)
...
...
@@ -174,7 +175,7 @@ void hi_sdsfree(hisds s) {
* the output will be "6" as the string was modified but the logical length
* remains 6 bytes. */
void
hi_sdsupdatelen
(
hisds
s
)
{
in
t
reallen
=
strlen
(
s
);
size_
t
reallen
=
strlen
(
s
);
hi_sdssetlen
(
s
,
reallen
);
}
...
...
@@ -196,7 +197,7 @@ void hi_sdsclear(hisds s) {
hisds
hi_sdsMakeRoomFor
(
hisds
s
,
size_t
addlen
)
{
void
*
sh
,
*
newsh
;
size_t
avail
=
hi_sdsavail
(
s
);
size_t
len
,
newlen
;
size_t
len
,
newlen
,
reqlen
;
char
type
,
oldtype
=
s
[
-
1
]
&
HI_SDS_TYPE_MASK
;
int
hdrlen
;
...
...
@@ -205,7 +206,8 @@ hisds hi_sdsMakeRoomFor(hisds s, size_t addlen) {
len
=
hi_sdslen
(
s
);
sh
=
(
char
*
)
s
-
hi_sdsHdrSize
(
oldtype
);
newlen
=
(
len
+
addlen
);
reqlen
=
newlen
=
(
len
+
addlen
);
if
(
newlen
<=
len
)
return
NULL
;
/* Catch size_t overflow */
if
(
newlen
<
HI_SDS_MAX_PREALLOC
)
newlen
*=
2
;
else
...
...
@@ -219,6 +221,7 @@ hisds hi_sdsMakeRoomFor(hisds s, size_t addlen) {
if
(
type
==
HI_SDS_TYPE_5
)
type
=
HI_SDS_TYPE_8
;
hdrlen
=
hi_sdsHdrSize
(
type
);
if
(
hdrlen
+
newlen
+
1
<=
reqlen
)
return
NULL
;
/* Catch size_t overflow */
if
(
oldtype
==
type
)
{
newsh
=
hi_s_realloc
(
sh
,
hdrlen
+
newlen
+
1
);
if
(
newsh
==
NULL
)
return
NULL
;
...
...
@@ -580,7 +583,7 @@ hisds hi_sdscatprintf(hisds s, const char *fmt, ...) {
*/
hisds
hi_sdscatfmt
(
hisds
s
,
char
const
*
fmt
,
...)
{
const
char
*
f
=
fmt
;
int
i
;
long
i
;
va_list
ap
;
va_start
(
ap
,
fmt
);
...
...
@@ -753,16 +756,16 @@ int hi_sdsrange(hisds s, ssize_t start, ssize_t end) {
return
0
;
}
/* Apply tolower() to every character of the
hi
sds string 's'. */
/* Apply tolower() to every character of the sds string 's'. */
void
hi_sdstolower
(
hisds
s
)
{
in
t
len
=
hi_sdslen
(
s
),
j
;
size_
t
len
=
hi_sdslen
(
s
),
j
;
for
(
j
=
0
;
j
<
len
;
j
++
)
s
[
j
]
=
tolower
(
s
[
j
]);
}
/* Apply toupper() to every character of the
hi
sds string 's'. */
/* Apply toupper() to every character of the sds string 's'. */
void
hi_sdstoupper
(
hisds
s
)
{
in
t
len
=
hi_sdslen
(
s
),
j
;
size_
t
len
=
hi_sdslen
(
s
),
j
;
for
(
j
=
0
;
j
<
len
;
j
++
)
s
[
j
]
=
toupper
(
s
[
j
]);
}
...
...
deps/hiredis/sds.h
View file @
e7a3d3d1
...
...
@@ -35,9 +35,11 @@
#define HI_SDS_MAX_PREALLOC (1024*1024)
#ifdef _MSC_VER
#define __attribute__(x)
typedef
long
long
ssize_t
;
#define SSIZE_MAX (LLONG_MAX >> 1)
#ifndef __clang__
#define __attribute__(x)
#endif
#endif
#include <sys/types.h>
...
...
deps/hiredis/sockcompat.c
View file @
e7a3d3d1
...
...
@@ -180,10 +180,17 @@ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen)
/* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as
* EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX
* logic consistent. */
if
(
errno
==
EWOULDBLOCK
)
{
* logic consistent.
* Additionally, WSAALREADY is can be reported as WSAEINVAL to and this is
* translated to EIO. Convert appropriately
*/
int
err
=
errno
;
if
(
err
==
EWOULDBLOCK
)
{
errno
=
EINPROGRESS
;
}
else
if
(
err
==
EIO
)
{
errno
=
EALREADY
;
}
return
ret
!=
SOCKET_ERROR
?
ret
:
-
1
;
}
...
...
@@ -205,6 +212,14 @@ int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, sockle
}
else
{
ret
=
getsockopt
(
sockfd
,
level
,
optname
,
(
char
*
)
optval
,
optlen
);
}
if
(
ret
!=
SOCKET_ERROR
&&
level
==
SOL_SOCKET
&&
optname
==
SO_ERROR
)
{
/* translate SO_ERROR codes, if non-zero */
int
err
=
*
(
int
*
)
optval
;
if
(
err
!=
0
)
{
err
=
_wsaErrorToErrno
(
err
);
*
(
int
*
)
optval
=
err
;
}
}
_updateErrno
(
ret
!=
SOCKET_ERROR
);
return
ret
!=
SOCKET_ERROR
?
ret
:
-
1
;
}
...
...
@@ -245,4 +260,21 @@ int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
_updateErrno
(
ret
!=
SOCKET_ERROR
);
return
ret
!=
SOCKET_ERROR
?
ret
:
-
1
;
}
int
win32_redisKeepAlive
(
SOCKET
sockfd
,
int
interval_ms
)
{
struct
tcp_keepalive
cfg
;
DWORD
bytes_in
;
int
res
;
cfg
.
onoff
=
1
;
cfg
.
keepaliveinterval
=
interval_ms
;
cfg
.
keepalivetime
=
interval_ms
;
res
=
WSAIoctl
(
sockfd
,
SIO_KEEPALIVE_VALS
,
&
cfg
,
sizeof
(
struct
tcp_keepalive
),
NULL
,
0
,
&
bytes_in
,
NULL
,
NULL
);
return
res
==
0
?
0
:
_wsaErrorToErrno
(
res
);
}
#endif
/* _WIN32 */
deps/hiredis/sockcompat.h
View file @
e7a3d3d1
...
...
@@ -50,6 +50,7 @@
#include <ws2tcpip.h>
#include <stddef.h>
#include <errno.h>
#include <mstcpip.h>
#ifdef _MSC_VER
typedef
long
long
ssize_t
;
...
...
@@ -71,6 +72,8 @@ ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags);
typedef
ULONG
nfds_t
;
int
win32_poll
(
struct
pollfd
*
fds
,
nfds_t
nfds
,
int
timeout
);
int
win32_redisKeepAlive
(
SOCKET
sockfd
,
int
interval_ms
);
#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION
#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res)
#undef gai_strerror
...
...
deps/hiredis/ssl.c
View file @
e7a3d3d1
...
...
@@ -32,6 +32,7 @@
#include "hiredis.h"
#include "async.h"
#include "net.h"
#include <assert.h>
#include <errno.h>
...
...
@@ -39,6 +40,14 @@
#ifdef _WIN32
#include <windows.h>
#include <wincrypt.h>
#ifdef OPENSSL_IS_BORINGSSL
#undef X509_NAME
#undef X509_EXTENSIONS
#undef PKCS7_ISSUER_AND_SERIAL
#undef PKCS7_SIGNER_INFO
#undef OCSP_REQUEST
#undef OCSP_RESPONSE
#endif
#else
#include <pthread.h>
#endif
...
...
@@ -219,6 +228,25 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
const
char
*
cert_filename
,
const
char
*
private_key_filename
,
const
char
*
server_name
,
redisSSLContextError
*
error
)
{
redisSSLOptions
options
=
{
.
cacert_filename
=
cacert_filename
,
.
capath
=
capath
,
.
cert_filename
=
cert_filename
,
.
private_key_filename
=
private_key_filename
,
.
server_name
=
server_name
,
.
verify_mode
=
REDIS_SSL_VERIFY_PEER
,
};
return
redisCreateSSLContextWithOptions
(
&
options
,
error
);
}
redisSSLContext
*
redisCreateSSLContextWithOptions
(
redisSSLOptions
*
options
,
redisSSLContextError
*
error
)
{
const
char
*
cacert_filename
=
options
->
cacert_filename
;
const
char
*
capath
=
options
->
capath
;
const
char
*
cert_filename
=
options
->
cert_filename
;
const
char
*
private_key_filename
=
options
->
private_key_filename
;
const
char
*
server_name
=
options
->
server_name
;
#ifdef _WIN32
HCERTSTORE
win_store
=
NULL
;
PCCERT_CONTEXT
win_ctx
=
NULL
;
...
...
@@ -235,7 +263,7 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
}
SSL_CTX_set_options
(
ctx
->
ssl_ctx
,
SSL_OP_NO_SSLv2
|
SSL_OP_NO_SSLv3
);
SSL_CTX_set_verify
(
ctx
->
ssl_ctx
,
SSL_VERIFY_PEER
,
NULL
);
SSL_CTX_set_verify
(
ctx
->
ssl_ctx
,
options
->
verify_mode
,
NULL
);
if
((
cert_filename
!=
NULL
&&
private_key_filename
==
NULL
)
||
(
private_key_filename
!=
NULL
&&
cert_filename
==
NULL
))
{
...
...
@@ -273,6 +301,11 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
if
(
error
)
*
error
=
REDIS_SSL_CTX_CA_CERT_LOAD_FAILED
;
goto
error
;
}
}
else
{
if
(
!
SSL_CTX_set_default_verify_paths
(
ctx
->
ssl_ctx
))
{
if
(
error
)
*
error
=
REDIS_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED
;
goto
error
;
}
}
if
(
cert_filename
)
{
...
...
@@ -560,6 +593,7 @@ static void redisSSLAsyncWrite(redisAsyncContext *ac) {
}
redisContextFuncs
redisContextSSLFuncs
=
{
.
close
=
redisNetClose
,
.
free_privctx
=
redisSSLFree
,
.
async_read
=
redisSSLAsyncRead
,
.
async_write
=
redisSSLAsyncWrite
,
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment