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
39436b21
Unverified
Commit
39436b21
authored
Oct 28, 2020
by
filipe oliveira
Committed by
GitHub
Oct 28, 2020
Browse files
TLS Support for redis-benchmark (#7959)
parent
66037309
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
39436b21
...
...
@@ -257,9 +257,9 @@ REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX)
REDIS_SENTINEL_NAME
=
redis-sentinel
$(PROG_SUFFIX)
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o gopher.o tracking.o connection.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o
REDIS_CLI_NAME
=
redis-cli
$(PROG_SUFFIX)
REDIS_CLI_OBJ
=
anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o
REDIS_CLI_OBJ
=
anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o
cli_common.o
REDIS_BENCHMARK_NAME
=
redis-benchmark
$(PROG_SUFFIX)
REDIS_BENCHMARK_OBJ
=
ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o
REDIS_BENCHMARK_OBJ
=
ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o
cli_common.o
REDIS_CHECK_RDB_NAME
=
redis-check-rdb
$(PROG_SUFFIX)
REDIS_CHECK_AOF_NAME
=
redis-check-aof
$(PROG_SUFFIX)
...
...
src/cli_common.c
0 → 100644
View file @
39436b21
/* CLI (command line interface) common methods
*
* Copyright (c) 2020, Redis Labs
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "cli_common.h"
#include <errno.h>
#include <hiredis.h>
#include <sdscompat.h>
/* Use hiredis' sds compat header that maps sds calls to their hi_ variants */
#include <sds.h>
/* use sds.h from hiredis, so that only one set of sds functions will be present in the binary */
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <hiredis_ssl.h>
#endif
/* Wrapper around redisSecureConnection to avoid hiredis_ssl dependencies if
* not building with TLS support.
*/
int
cliSecureConnection
(
redisContext
*
c
,
cliSSLconfig
config
,
const
char
**
err
)
{
#ifdef USE_OPENSSL
static
SSL_CTX
*
ssl_ctx
=
NULL
;
if
(
!
ssl_ctx
)
{
ssl_ctx
=
SSL_CTX_new
(
SSLv23_client_method
());
if
(
!
ssl_ctx
)
{
*
err
=
"Failed to create SSL_CTX"
;
goto
error
;
}
SSL_CTX_set_options
(
ssl_ctx
,
SSL_OP_NO_SSLv2
|
SSL_OP_NO_SSLv3
);
SSL_CTX_set_verify
(
ssl_ctx
,
SSL_VERIFY_PEER
,
NULL
);
if
(
config
.
cacert
||
config
.
cacertdir
)
{
if
(
!
SSL_CTX_load_verify_locations
(
ssl_ctx
,
config
.
cacert
,
config
.
cacertdir
))
{
*
err
=
"Invalid CA Certificate File/Directory"
;
goto
error
;
}
}
else
{
if
(
!
SSL_CTX_set_default_verify_paths
(
ssl_ctx
))
{
*
err
=
"Failed to use default CA paths"
;
goto
error
;
}
}
if
(
config
.
cert
&&
!
SSL_CTX_use_certificate_chain_file
(
ssl_ctx
,
config
.
cert
))
{
*
err
=
"Invalid client certificate"
;
goto
error
;
}
if
(
config
.
key
&&
!
SSL_CTX_use_PrivateKey_file
(
ssl_ctx
,
config
.
key
,
SSL_FILETYPE_PEM
))
{
*
err
=
"Invalid private key"
;
goto
error
;
}
}
SSL
*
ssl
=
SSL_new
(
ssl_ctx
);
if
(
!
ssl
)
{
*
err
=
"Failed to create SSL object"
;
return
REDIS_ERR
;
}
if
(
config
.
sni
&&
!
SSL_set_tlsext_host_name
(
ssl
,
config
.
sni
))
{
*
err
=
"Failed to configure SNI"
;
SSL_free
(
ssl
);
return
REDIS_ERR
;
}
return
redisInitiateSSL
(
c
,
ssl
);
error:
SSL_CTX_free
(
ssl_ctx
);
ssl_ctx
=
NULL
;
return
REDIS_ERR
;
#else
(
void
)
config
;
(
void
)
c
;
(
void
)
err
;
return
REDIS_OK
;
#endif
}
/* Wrapper around hiredis to allow arbitrary reads and writes.
*
* We piggybacks on top of hiredis to achieve transparent TLS support,
* and use its internal buffers so it can co-exist with commands
* previously/later issued on the connection.
*
* Interface is close to enough to read()/write() so things should mostly
* work transparently.
*/
/* Write a raw buffer through a redisContext. If we already have something
* in the buffer (leftovers from hiredis operations) it will be written
* as well.
*/
ssize_t
cliWriteConn
(
redisContext
*
c
,
const
char
*
buf
,
size_t
buf_len
)
{
int
done
=
0
;
/* Append data to buffer which is *usually* expected to be empty
* but we don't assume that, and write.
*/
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
buf
,
buf_len
);
if
(
redisBufferWrite
(
c
,
&
done
)
==
REDIS_ERR
)
{
if
(
!
(
c
->
flags
&
REDIS_BLOCK
))
errno
=
EAGAIN
;
/* On error, we assume nothing was written and we roll back the
* buffer to its original state.
*/
if
(
sdslen
(
c
->
obuf
)
>
buf_len
)
sdsrange
(
c
->
obuf
,
0
,
-
(
buf_len
+
1
));
else
sdsclear
(
c
->
obuf
);
return
-
1
;
}
/* If we're done, free up everything. We may have written more than
* buf_len (if c->obuf was not initially empty) but we don't have to
* tell.
*/
if
(
done
)
{
sdsclear
(
c
->
obuf
);
return
buf_len
;
}
/* Write was successful but we have some leftovers which we should
* remove from the buffer.
*
* Do we still have data that was there prior to our buf? If so,
* restore buffer to it's original state and report no new data was
* writen.
*/
if
(
sdslen
(
c
->
obuf
)
>
buf_len
)
{
sdsrange
(
c
->
obuf
,
0
,
-
(
buf_len
+
1
));
return
0
;
}
/* At this point we're sure no prior data is left. We flush the buffer
* and report how much we've written.
*/
size_t
left
=
sdslen
(
c
->
obuf
);
sdsclear
(
c
->
obuf
);
return
buf_len
-
left
;
}
/* Wrapper around OpenSSL (libssl and libcrypto) initialisation
*/
int
cliSecureInit
()
{
#ifdef USE_OPENSSL
ERR_load_crypto_strings
();
SSL_load_error_strings
();
SSL_library_init
();
#endif
return
REDIS_OK
;
}
src/cli_common.h
0 → 100644
View file @
39436b21
#ifndef __CLICOMMON_H
#define __CLICOMMON_H
#include <hiredis.h>
typedef
struct
cliSSLconfig
{
/* Requested SNI, or NULL */
char
*
sni
;
/* CA Certificate file, or NULL */
char
*
cacert
;
/* Directory where trusted CA certificates are stored, or NULL */
char
*
cacertdir
;
/* Client certificate to authenticate with, or NULL */
char
*
cert
;
/* Private key file to authenticate with, or NULL */
char
*
key
;
}
cliSSLconfig
;
/* Wrapper around redisSecureConnection to avoid hiredis_ssl dependencies if
* not building with TLS support.
*/
int
cliSecureConnection
(
redisContext
*
c
,
cliSSLconfig
config
,
const
char
**
err
);
/* Wrapper around hiredis to allow arbitrary reads and writes.
*
* We piggybacks on top of hiredis to achieve transparent TLS support,
* and use its internal buffers so it can co-exist with commands
* previously/later issued on the connection.
*
* Interface is close to enough to read()/write() so things should mostly
* work transparently.
*/
/* Write a raw buffer through a redisContext. If we already have something
* in the buffer (leftovers from hiredis operations) it will be written
* as well.
*/
ssize_t
cliWriteConn
(
redisContext
*
c
,
const
char
*
buf
,
size_t
buf_len
);
/* Wrapper around OpenSSL (libssl and libcrypto) initialisation.
*/
int
cliSecureInit
();
#endif
/* __CLICOMMON_H */
src/redis-benchmark.c
View file @
39436b21
...
...
@@ -46,13 +46,19 @@
#include <sdscompat.h>
/* Use hiredis' sds compat header that maps sds calls to their hi_ variants */
#include <sds.h>
/* Use hiredis sds. */
#include "ae.h"
#include "hiredis.h"
#include <hiredis.h>
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <hiredis_ssl.h>
#endif
#include "adlist.h"
#include "dict.h"
#include "zmalloc.h"
#include "atomicvar.h"
#include "crc16_slottable.h"
#include "hdr_histogram.h"
#include "cli_common.h"
#define UNUSED(V) ((void) V)
#define RANDPTR_INITIAL_SIZE 8
...
...
@@ -76,6 +82,8 @@ static struct config {
const
char
*
hostip
;
int
hostport
;
const
char
*
hostsocket
;
int
tls
;
struct
cliSSLconfig
sslconfig
;
int
numclients
;
redisAtomic
int
liveclients
;
int
requests
;
...
...
@@ -280,6 +288,13 @@ static redisContext *getRedisContext(const char *ip, int port,
fprintf
(
stderr
,
"%s: %s
\n
"
,
hostsocket
,
err
);
goto
cleanup
;
}
if
(
config
.
tls
==
1
)
{
const
char
*
err
=
NULL
;
if
(
cliSecureConnection
(
ctx
,
config
.
sslconfig
,
&
err
)
==
REDIS_ERR
&&
err
)
{
fprintf
(
stderr
,
"Could not negotiate a TLS connection: %s
\n
"
,
err
);
goto
cleanup
;
}
}
if
(
config
.
auth
==
NULL
)
return
ctx
;
if
(
config
.
user
==
NULL
)
...
...
@@ -308,6 +323,8 @@ cleanup:
return
NULL
;
}
static
redisConfig
*
getRedisConfig
(
const
char
*
ip
,
int
port
,
const
char
*
hostsocket
)
{
...
...
@@ -606,19 +623,26 @@ static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
c
->
start
=
ustime
();
c
->
latency
=
-
1
;
}
if
(
sdslen
(
c
->
obuf
)
>
c
->
written
)
{
const
ssize_t
buflen
=
sdslen
(
c
->
obuf
);
const
ssize_t
writeLen
=
buflen
-
c
->
written
;
if
(
writeLen
>
0
)
{
void
*
ptr
=
c
->
obuf
+
c
->
written
;
ssize_t
nwritten
=
write
(
c
->
context
->
fd
,
ptr
,
sdslen
(
c
->
obuf
)
-
c
->
written
);
if
(
nwritten
==
-
1
)
{
if
(
errno
!=
EPIPE
)
fprintf
(
stderr
,
"Writing to socket: %s
\n
"
,
strerror
(
errno
));
freeClient
(
c
);
return
;
}
c
->
written
+=
nwritten
;
if
(
sdslen
(
c
->
obuf
)
==
c
->
written
)
{
aeDeleteFileEvent
(
el
,
c
->
context
->
fd
,
AE_WRITABLE
);
aeCreateFileEvent
(
el
,
c
->
context
->
fd
,
AE_READABLE
,
readHandler
,
c
);
while
(
1
)
{
/* Optimistically try to write before checking if the file descriptor
* is actually writable. At worst we get EAGAIN. */
const
ssize_t
nwritten
=
cliWriteConn
(
c
->
context
,
ptr
,
writeLen
);
if
(
nwritten
!=
writeLen
)
{
if
(
nwritten
==
-
1
&&
errno
!=
EAGAIN
)
{
if
(
errno
!=
EPIPE
)
fprintf
(
stderr
,
"Error writing to the server: %s
\n
"
,
strerror
(
errno
));
freeClient
(
c
);
return
;
}
}
else
{
aeDeleteFileEvent
(
el
,
c
->
context
->
fd
,
AE_WRITABLE
);
aeCreateFileEvent
(
el
,
c
->
context
->
fd
,
AE_READABLE
,
readHandler
,
c
);
return
;
}
}
}
}
...
...
@@ -680,6 +704,13 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) {
fprintf
(
stderr
,
"%s: %s
\n
"
,
config
.
hostsocket
,
c
->
context
->
errstr
);
exit
(
1
);
}
if
(
config
.
tls
==
1
)
{
const
char
*
err
=
NULL
;
if
(
cliSecureConnection
(
c
->
context
,
config
.
sslconfig
,
&
err
)
==
REDIS_ERR
&&
err
)
{
fprintf
(
stderr
,
"Could not negotiate a TLS connection: %s
\n
"
,
err
);
exit
(
1
);
}
}
c
->
thread_id
=
thread_id
;
/* Suppress hiredis cleanup of unused buffers for max speed. */
c
->
context
->
reader
->
maxbuf
=
0
;
...
...
@@ -1471,6 +1502,25 @@ int parseOptions(int argc, const char **argv) {
}
else
if
(
!
strcmp
(
argv
[
i
],
"--help"
))
{
exit_status
=
0
;
goto
usage
;
#ifdef USE_OPENSSL
}
else
if
(
!
strcmp
(
argv
[
i
],
"--tls"
))
{
config
.
tls
=
1
;
}
else
if
(
!
strcmp
(
argv
[
i
],
"--sni"
))
{
if
(
lastarg
)
goto
invalid
;
config
.
sslconfig
.
sni
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
argv
[
i
],
"--cacertdir"
))
{
if
(
lastarg
)
goto
invalid
;
config
.
sslconfig
.
cacertdir
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
argv
[
i
],
"--cacert"
))
{
if
(
lastarg
)
goto
invalid
;
config
.
sslconfig
.
cacert
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
argv
[
i
],
"--cert"
))
{
if
(
lastarg
)
goto
invalid
;
config
.
sslconfig
.
cert
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
argv
[
i
],
"--key"
))
{
if
(
lastarg
)
goto
invalid
;
config
.
sslconfig
.
key
=
strdup
(
argv
[
++
i
]);
#endif
}
else
{
/* Assume the user meant to provide an option when the arg starts
* with a dash. We're done otherwise and should use the remainder
...
...
@@ -1518,6 +1568,16 @@ usage:
" -t <tests> Only run the comma separated list of tests. The test
\n
"
" names are the same as the ones produced as output.
\n
"
" -I Idle mode. Just open N idle connections and wait.
\n
"
#ifdef USE_OPENSSL
" --tls Establish a secure TLS connection.
\n
"
" --sni <host> Server name indication for TLS.
\n
"
" --cacert <file> CA Certificate file to verify with.
\n
"
" --cacertdir <dir> Directory where trusted CA certificates are stored.
\n
"
" If neither cacert nor cacertdir are specified, the default
\n
"
" system-wide trusted root certs configuration will apply.
\n
"
" --cert <file> Client certificate to authenticate with.
\n
"
" --key <file> Private key file to authenticate with.
\n
"
#endif
" --help Output this help and exit.
\n
"
" --version Output version and exit.
\n\n
"
"Examples:
\n\n
"
...
...
@@ -1642,6 +1702,12 @@ int main(int argc, const char **argv) {
tag
=
""
;
#ifdef USE_OPENSSL
if
(
config
.
tls
)
{
cliSecureInit
();
}
#endif
if
(
config
.
cluster_mode
)
{
// We only include the slot placeholder {tag} if cluster mode is enabled
tag
=
":{tag}"
;
...
...
src/redis-cli.c
View file @
39436b21
...
...
@@ -61,6 +61,7 @@
#include "help.h"
#include "anet.h"
#include "ae.h"
#include "cli_common.h"
#define UNUSED(V) ((void) V)
...
...
@@ -199,11 +200,7 @@ static struct config {
int
hostport
;
char
*
hostsocket
;
int
tls
;
char
*
sni
;
char
*
cacert
;
char
*
cacertdir
;
char
*
cert
;
char
*
key
;
cliSSLconfig
sslconfig
;
long
repeat
;
long
interval
;
int
dbnum
;
...
...
@@ -788,71 +785,6 @@ static int cliSelect(void) {
return
REDIS_ERR
;
}
/* Wrapper around redisSecureConnection to avoid hiredis_ssl dependencies if
* not building with TLS support.
*/
static
int
cliSecureConnection
(
redisContext
*
c
,
const
char
**
err
)
{
#ifdef USE_OPENSSL
static
SSL_CTX
*
ssl_ctx
=
NULL
;
if
(
!
ssl_ctx
)
{
ssl_ctx
=
SSL_CTX_new
(
SSLv23_client_method
());
if
(
!
ssl_ctx
)
{
*
err
=
"Failed to create SSL_CTX"
;
goto
error
;
}
SSL_CTX_set_options
(
ssl_ctx
,
SSL_OP_NO_SSLv2
|
SSL_OP_NO_SSLv3
);
SSL_CTX_set_verify
(
ssl_ctx
,
SSL_VERIFY_PEER
,
NULL
);
if
(
config
.
cacert
||
config
.
cacertdir
)
{
if
(
!
SSL_CTX_load_verify_locations
(
ssl_ctx
,
config
.
cacert
,
config
.
cacertdir
))
{
*
err
=
"Invalid CA Certificate File/Directory"
;
goto
error
;
}
}
else
{
if
(
!
SSL_CTX_set_default_verify_paths
(
ssl_ctx
))
{
*
err
=
"Failed to use default CA paths"
;
goto
error
;
}
}
if
(
config
.
cert
&&
!
SSL_CTX_use_certificate_chain_file
(
ssl_ctx
,
config
.
cert
))
{
*
err
=
"Invalid client certificate"
;
goto
error
;
}
if
(
config
.
key
&&
!
SSL_CTX_use_PrivateKey_file
(
ssl_ctx
,
config
.
key
,
SSL_FILETYPE_PEM
))
{
*
err
=
"Invalid private key"
;
goto
error
;
}
}
SSL
*
ssl
=
SSL_new
(
ssl_ctx
);
if
(
!
ssl
)
{
*
err
=
"Failed to create SSL object"
;
return
REDIS_ERR
;
}
if
(
config
.
sni
&&
!
SSL_set_tlsext_host_name
(
ssl
,
config
.
sni
))
{
*
err
=
"Failed to configure SNI"
;
SSL_free
(
ssl
);
return
REDIS_ERR
;
}
return
redisInitiateSSL
(
c
,
ssl
);
error:
SSL_CTX_free
(
ssl_ctx
);
ssl_ctx
=
NULL
;
return
REDIS_ERR
;
#else
(
void
)
c
;
(
void
)
err
;
return
REDIS_OK
;
#endif
}
/* Select RESP3 mode if redis-cli was started with the -3 option. */
static
int
cliSwitchProto
(
void
)
{
redisReply
*
reply
;
...
...
@@ -886,7 +818,7 @@ static int cliConnect(int flags) {
if
(
!
context
->
err
&&
config
.
tls
)
{
const
char
*
err
=
NULL
;
if
(
cliSecureConnection
(
context
,
&
err
)
==
REDIS_ERR
&&
err
)
{
if
(
cliSecureConnection
(
context
,
config
.
sslconfig
,
&
err
)
==
REDIS_ERR
&&
err
)
{
fprintf
(
stderr
,
"Could not negotiate a TLS connection: %s
\n
"
,
err
);
redisFree
(
context
);
context
=
NULL
;
...
...
@@ -1484,7 +1416,7 @@ static redisReply *reconnectingRedisCommand(redisContext *c, const char *fmt, ..
c
=
redisConnect
(
config
.
hostip
,
config
.
hostport
);
if
(
!
c
->
err
&&
config
.
tls
)
{
const
char
*
err
=
NULL
;
if
(
cliSecureConnection
(
c
,
&
err
)
==
REDIS_ERR
&&
err
)
{
if
(
cliSecureConnection
(
c
,
config
.
sslconfig
,
&
err
)
==
REDIS_ERR
&&
err
)
{
fprintf
(
stderr
,
"TLS Error: %s
\n
"
,
err
);
exit
(
1
);
}
...
...
@@ -1700,15 +1632,15 @@ static int parseOptions(int argc, char **argv) {
}
else
if
(
!
strcmp
(
argv
[
i
],
"--tls"
))
{
config
.
tls
=
1
;
}
else
if
(
!
strcmp
(
argv
[
i
],
"--sni"
)
&&
!
lastarg
)
{
config
.
sni
=
argv
[
++
i
];
config
.
sslconfig
.
sni
=
argv
[
++
i
];
}
else
if
(
!
strcmp
(
argv
[
i
],
"--cacertdir"
)
&&
!
lastarg
)
{
config
.
cacertdir
=
argv
[
++
i
];
config
.
sslconfig
.
cacertdir
=
argv
[
++
i
];
}
else
if
(
!
strcmp
(
argv
[
i
],
"--cacert"
)
&&
!
lastarg
)
{
config
.
cacert
=
argv
[
++
i
];
config
.
sslconfig
.
cacert
=
argv
[
++
i
];
}
else
if
(
!
strcmp
(
argv
[
i
],
"--cert"
)
&&
!
lastarg
)
{
config
.
cert
=
argv
[
++
i
];
config
.
sslconfig
.
cert
=
argv
[
++
i
];
}
else
if
(
!
strcmp
(
argv
[
i
],
"--key"
)
&&
!
lastarg
)
{
config
.
key
=
argv
[
++
i
];
config
.
sslconfig
.
key
=
argv
[
++
i
];
#endif
}
else
if
(
!
strcmp
(
argv
[
i
],
"-v"
)
||
!
strcmp
(
argv
[
i
],
"--version"
))
{
sds
version
=
cliVersion
();
...
...
@@ -2677,7 +2609,7 @@ static int clusterManagerNodeConnect(clusterManagerNode *node) {
node
->
context
=
redisConnect
(
node
->
ip
,
node
->
port
);
if
(
!
node
->
context
->
err
&&
config
.
tls
)
{
const
char
*
err
=
NULL
;
if
(
cliSecureConnection
(
node
->
context
,
&
err
)
==
REDIS_ERR
&&
err
)
{
if
(
cliSecureConnection
(
node
->
context
,
config
.
sslconfig
,
&
err
)
==
REDIS_ERR
&&
err
)
{
fprintf
(
stderr
,
"TLS Error: %s
\n
"
,
err
);
redisFree
(
node
->
context
);
node
->
context
=
NULL
;
...
...
@@ -6898,72 +6830,6 @@ void sendCapa() {
sendReplconf
(
"capa"
,
"eof"
);
}
/* Wrapper around hiredis to allow arbitrary reads and writes.
*
* We piggybacks on top of hiredis to achieve transparent TLS support,
* and use its internal buffers so it can co-exist with commands
* previously/later issued on the connection.
*
* Interface is close to enough to read()/write() so things should mostly
* work transparently.
*/
/* Write a raw buffer through a redisContext. If we already have something
* in the buffer (leftovers from hiredis operations) it will be written
* as well.
*/
static
ssize_t
writeConn
(
redisContext
*
c
,
const
char
*
buf
,
size_t
buf_len
)
{
int
done
=
0
;
/* Append data to buffer which is *usually* expected to be empty
* but we don't assume that, and write.
*/
c
->
obuf
=
sdscatlen
(
c
->
obuf
,
buf
,
buf_len
);
if
(
redisBufferWrite
(
c
,
&
done
)
==
REDIS_ERR
)
{
if
(
!
(
c
->
flags
&
REDIS_BLOCK
))
errno
=
EAGAIN
;
/* On error, we assume nothing was written and we roll back the
* buffer to its original state.
*/
if
(
sdslen
(
c
->
obuf
)
>
buf_len
)
sdsrange
(
c
->
obuf
,
0
,
-
(
buf_len
+
1
));
else
sdsclear
(
c
->
obuf
);
return
-
1
;
}
/* If we're done, free up everything. We may have written more than
* buf_len (if c->obuf was not initially empty) but we don't have to
* tell.
*/
if
(
done
)
{
sdsclear
(
c
->
obuf
);
return
buf_len
;
}
/* Write was successful but we have some leftovers which we should
* remove from the buffer.
*
* Do we still have data that was there prior to our buf? If so,
* restore buffer to it's original state and report no new data was
* writen.
*/
if
(
sdslen
(
c
->
obuf
)
>
buf_len
)
{
sdsrange
(
c
->
obuf
,
0
,
-
(
buf_len
+
1
));
return
0
;
}
/* At this point we're sure no prior data is left. We flush the buffer
* and report how much we've written.
*/
size_t
left
=
sdslen
(
c
->
obuf
);
sdsclear
(
c
->
obuf
);
return
buf_len
-
left
;
}
/* Read raw bytes through a redisContext. The read operation is not greedy
* and may not fill the buffer entirely.
*/
...
...
@@ -6984,7 +6850,7 @@ unsigned long long sendSync(redisContext *c, char *out_eof) {
ssize_t
nread
;
/* Send the SYNC command. */
if
(
w
riteConn
(
c
,
"SYNC
\r\n
"
,
6
)
!=
6
)
{
if
(
cliW
riteConn
(
c
,
"SYNC
\r\n
"
,
6
)
!=
6
)
{
fprintf
(
stderr
,
"Error writing to master
\n
"
);
exit
(
1
);
}
...
...
@@ -7249,7 +7115,7 @@ static void pipeMode(void) {
while
(
1
)
{
/* Transfer current buffer to server. */
if
(
obuf_len
!=
0
)
{
ssize_t
nwritten
=
w
riteConn
(
context
,
obuf
+
obuf_pos
,
obuf_len
);
ssize_t
nwritten
=
cliW
riteConn
(
context
,
obuf
+
obuf_pos
,
obuf_len
);
if
(
nwritten
==
-
1
)
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EINTR
)
{
...
...
@@ -8229,9 +8095,7 @@ int main(int argc, char **argv) {
#ifdef USE_OPENSSL
if
(
config
.
tls
)
{
ERR_load_crypto_strings
();
SSL_load_error_strings
();
SSL_library_init
();
cliSecureInit
();
}
#endif
...
...
tests/support/benchmark.tcl
View file @
39436b21
proc redisbenchmark_tls_config
{
testsdir
}
{
set tlsdir
[
file join $testsdir tls
]
set cert
[
file join $tlsdir redis.crt
]
set key
[
file join $tlsdir redis.key
]
set cacert
[
file join $tlsdir ca.crt
]
if
{
$::tls
}
{
return
[
list --tls --cert $cert --key $key --cacert $cacert
]
}
else
{
return
{}
}
}
proc redisbenchmark
{
host port
{
opts
{}}}
{
set cmd
[
list src/redis-benchmark -h $host -p $port
]
lappend cmd
{*}
[
redisbenchmark_tls_config
"tests"
]
lappend cmd
{*}
$opts
return $cmd
}
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