Skip to content

Commit 7202bf7

Browse files
nikolapajkovskymattcaswell
authored andcommitted
handshake: allow sharing SSL_CTX within thread
Allow use of -s option for ossl_lib_ctx pool test. Tested againts the master openssl branch. sharing SSL_CTX on: $ ./handshake -P /Users/npajkovsky/openssl/openssl/test/certs 500 Average time per handshake: 18248.810300us Handshakes per second: 12385.634151 sharing SSL_CTX off: $ ./handshake -s -P /Users/npajkovsky/openssl/openssl/test/certs 500 Average time per handshake: 51546.385400us Handshakes per second: 6285.852934 Signed-off-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Viktor Dukhovni <[email protected]> Reviewed-by: Matt Caswell <[email protected]> (Merged from #25)
1 parent d5d6ae2 commit 7202bf7

File tree

3 files changed

+66
-16
lines changed

3 files changed

+66
-16
lines changed

README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ handshake [-t] [-s] <certsdir> <threadcount>
5858
-p - use ossl_lib_ctx per thread
5959
-P - use ossl_lib_ctx pool (can be combined with -s. If sharing is enabled, ssl_ctx
6060
is shared within single thread)
61+
-o - set ossl_lib_ctx pool size (use only with -P)
6162
certsdir - Directory where the test can locate servercert.pem and serverkey.pem
6263
threadcount - Number of concurrent threads to run in test
6364

source/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ clean:
88
CPPFLAGS += -I$(TARGET_OSSL_INCLUDE_PATH) -I.
99
# For second include path, i.e. out of tree build of OpenSSL uncomment this:
1010
# CPPFLAGS += -I$(TARGET_OSSL_INCLUDE_PATH2)
11-
CFLAGS += -pthread -O2
11+
CFLAGS += -pthread -O3
1212
LDFLAGS += -L$(TARGET_OSSL_LIBRARY_PATH) -L.
1313
# For setting RUNPATH on built executables uncomment this:
1414
# LDFLAGS += -Wl,-rpath,$(TARGET_OSSL_LIBRARY_PATH)

source/handshake.c

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdlib.h>
1111
#include <stdio.h>
1212
#include <string.h>
13+
#include <errno.h>
1314
#ifndef _WIN32
1415
# include <libgen.h>
1516
# include <unistd.h>
@@ -22,21 +23,21 @@
2223
#include "perflib/perflib.h"
2324

2425
#define NUM_CALLS_PER_TEST 10000
25-
#define OSSL_LIB_CTX_POOL_SIZE 16
2626

2727
int err = 0;
2828

2929
static SSL_CTX *sctx = NULL, *cctx = NULL;
3030
static int share_ctx = 1;
3131
static char *cert = NULL;
3232
static char *privkey = NULL;
33-
static OSSL_LIB_CTX *libctx_pool[OSSL_LIB_CTX_POOL_SIZE] = { NULL };
33+
static OSSL_LIB_CTX **libctx_pool = NULL;
3434

3535

3636
OSSL_TIME *times;
3737

3838
static int threadcount;
3939
size_t num_calls;
40+
static long ossl_lib_ctx_pool_size = 16;
4041

4142
typedef enum {
4243
TC_SSL_CTX,
@@ -154,9 +155,8 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
154155

155156
start = ossl_time_now();
156157

157-
libctx = libctx_pool[num % OSSL_LIB_CTX_POOL_SIZE];
158-
159-
for (i = 0; i < num_calls / threadcount; i++) {
158+
libctx = libctx_pool[num % ossl_lib_ctx_pool_size];
159+
if (share_ctx == 1) {
160160
if (!perflib_create_ossl_lib_ctx_pair(libctx,
161161
TLS_server_method(),
162162
TLS_client_method(),
@@ -166,17 +166,37 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
166166
err = 1;
167167
return;
168168
}
169+
}
169170

171+
for (i = 0; i < num_calls / threadcount; ++i) {
172+
if (share_ctx == 0) {
173+
if (!perflib_create_ossl_lib_ctx_pair(libctx,
174+
TLS_server_method(),
175+
TLS_client_method(),
176+
0, 0, &lsctx, &lcctx, cert,
177+
privkey)) {
178+
fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__);
179+
err = 1;
180+
return;
181+
}
182+
}
170183

171184
ret = perflib_create_ssl_objects(lsctx, lcctx, &serverssl, &clientssl,
172185
NULL, NULL);
173186
ret &= perflib_create_ssl_connection(serverssl, clientssl,
174187
SSL_ERROR_NONE);
175188
perflib_shutdown_ssl_connection(serverssl, clientssl);
176189
serverssl = clientssl = NULL;
190+
if (share_ctx == 0) {
191+
SSL_CTX_free(lsctx);
192+
SSL_CTX_free(lcctx);
193+
lsctx = lcctx = NULL;
194+
}
195+
}
196+
197+
if (share_ctx == 1) {
177198
SSL_CTX_free(lsctx);
178199
SSL_CTX_free(lcctx);
179-
lsctx = lcctx = NULL;
180200
}
181201

182202
end = ossl_time_now();
@@ -186,8 +206,13 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
186206
err = 1;
187207
}
188208

189-
static int init_ossl_lib_ctx_pool() {
190-
for (int i = 0; i < OSSL_LIB_CTX_POOL_SIZE; ++i) {
209+
static int init_ossl_lib_ctx_pool()
210+
{
211+
libctx_pool = OPENSSL_malloc(ossl_lib_ctx_pool_size * sizeof(*libctx_pool));
212+
if (libctx_pool == NULL)
213+
return 1;
214+
215+
for (int i = 0; i < ossl_lib_ctx_pool_size; ++i) {
191216
libctx_pool[i] = OSSL_LIB_CTX_new();
192217
if (libctx_pool[i] == NULL) {
193218
fprintf(stderr, "%s:%d: Failed to create ossl lib context\n", __FILE__, __LINE__);
@@ -198,10 +223,13 @@ static int init_ossl_lib_ctx_pool() {
198223
return 1;
199224
}
200225

201-
static void free_ossl_lib_ctx_pool() {
202-
for (int i = 0; i < OSSL_LIB_CTX_POOL_SIZE; ++i) {
226+
static void free_ossl_lib_ctx_pool()
227+
{
228+
for (int i = 0; i < ossl_lib_ctx_pool_size; ++i) {
203229
OSSL_LIB_CTX_free(libctx_pool[i]);
204230
}
231+
232+
OPENSSL_free(libctx_pool);
205233
}
206234

207235
static int test_ossl_lib_ctx_pool(size_t threadcount, OSSL_TIME *duration)
@@ -213,22 +241,23 @@ static int test_ossl_lib_ctx_pool(size_t threadcount, OSSL_TIME *duration)
213241
goto err;
214242

215243
ret = perflib_run_multi_thread_test(do_handshake_ossl_lib_ctx_pool, threadcount, duration);
216-
if (!ret) {
244+
if (!ret)
217245
printf("Failed to run the test\n");
218-
}
219246

220247
err:
221248
free_ossl_lib_ctx_pool();
222249

223250
return ret;
224251
}
225252

226-
void usage(const char *progname) {
227-
printf("Usage: %s [-t] [-s] certsdir threadcount\n", progname);
253+
void usage(const char *progname)
254+
{
255+
printf("Usage: %s [-t] [-s] [-p] [-P] [-o] certsdir threadcount\n", progname);
228256
printf("-t - terse output\n");
229257
printf("-s - disable context sharing\n");
230258
printf("-p - use ossl_lib_ctx per thread\n");
231259
printf("-P - use ossl_lib_ctx pool\n");
260+
printf("-o - set ossl_lib_ctx pool size\n");
232261
}
233262

234263
int main(int argc, char * const argv[])
@@ -241,9 +270,10 @@ int main(int argc, char * const argv[])
241270
int terse = 0;
242271
int opt;
243272
int p_flag = 0, P_flag = 0;
273+
char *endptr = NULL;
244274
test_case_t test_case = TC_SSL_CTX;
245275

246-
while ((opt = getopt(argc, argv, "tspP")) != -1) {
276+
while ((opt = getopt(argc, argv, "tspPo:")) != -1) {
247277
switch (opt) {
248278
case 't':
249279
terse = 1;
@@ -259,6 +289,25 @@ int main(int argc, char * const argv[])
259289
P_flag = 1;
260290
test_case = TC_OSSL_LIB_CTX_POOL;
261291
break;
292+
case 'o':
293+
errno = 0;
294+
ossl_lib_ctx_pool_size = strtol(optarg, &endptr, 0);
295+
if (errno == ERANGE && ossl_lib_ctx_pool_size == ULONG_MAX) {
296+
perror("Overflow occurred");
297+
usage(basename(argv[0]));
298+
return EXIT_FAILURE;
299+
}
300+
if (endptr == optarg || *endptr) {
301+
fprintf(stderr, "Invalid input: '%s'\n", optarg);
302+
usage(basename(argv[0]));
303+
return EXIT_FAILURE;
304+
}
305+
if (ossl_lib_ctx_pool_size < 1) {
306+
fprintf(stderr, "Pool size must be a > 0\n");
307+
usage(basename(argv[0]));
308+
return EXIT_FAILURE;
309+
}
310+
break;
262311
default:
263312
usage(basename(argv[0]));
264313
return EXIT_FAILURE;

0 commit comments

Comments
 (0)