Skip to content

Commit 5e1a24c

Browse files
nikolapajkovskyt8m
authored andcommitted
handshake: test SSL_CTX pool
use an SSL_CTX pool of the same size as the libctx pool size, with server and client SSL_CTX objects allocated alongside the associated libctx. | Threads | NoOpts | -p | -s | -s -P | -P | -s -p | -l | |---------+--------+------+------+-------+-------+-------+-------| | 1 | 1704 | 1065 | 1075 | 1077 | 1688 | 1073 | 1682 | | 2 | 3320 | 2100 | 2074 | 2073 | 3301 | 2083 | 3304 | | 4 | 6480 | 4098 | 4012 | 4096 | 6541 | 4070 | 6523 | | 8 | 11863 | 7518 | 7003 | 7537 | 11641 | 7405 | 11913 | | 16 | 12448 | 5867 | 5520 | 6048 | 13537 | 5889 | 13506 | | 32 | 12200 | 5147 | 5588 | 5330 | 13417 | 5085 | 13226 | | 64 | 12297 | 4938 | 5451 | 4845 | 13500 | 4873 | 13692 | There does not seem to be much of differece between using pool of lib_ctx with allocating ssl_ctx per thread (-P), and having having pre-allocated pool of lib_ctx alongside with associated (-l) libctx. Resolves: openssl/project#1228 Signed-off-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #27)
1 parent 9bca873 commit 5e1a24c

File tree

3 files changed

+110
-51
lines changed

3 files changed

+110
-51
lines changed

README

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

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 -O3
11+
CFLAGS += -pthread -O3 -Wall
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: 108 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,42 @@
2626

2727
int err = 0;
2828

29+
typedef enum {
30+
INIT_LIB_CTX,
31+
INIT_LIB_AND_SSL_CTX,
32+
} init_ctx;
33+
34+
struct ctxs {
35+
OSSL_LIB_CTX *libctx;
36+
SSL_CTX *sctx;
37+
SSL_CTX *cctx;
38+
};
39+
2940
static SSL_CTX *sctx = NULL, *cctx = NULL;
3041
static int share_ctx = 1;
3142
static char *cert = NULL;
3243
static char *privkey = NULL;
33-
static OSSL_LIB_CTX **libctx_pool = NULL;
34-
44+
static struct ctxs **ctx_pool = NULL;
3545

3646
size_t *counts;
3747

3848
static int threadcount;
3949
size_t num_calls;
40-
static long ossl_lib_ctx_pool_size = 16;
50+
static long pool_size = 16;
4151

4252
typedef enum {
4353
TC_SSL_CTX,
4454
TC_OSSL_LIB_CTX_PER_THREAD,
4555
TC_OSSL_LIB_CTX_POOL,
56+
TC_SSL_CTX_POOL,
4657
} test_case_t;
4758
OSSL_TIME max_time;
59+
static test_case_t test_case = TC_SSL_CTX;
4860

4961
static void do_handshake(size_t num)
5062
{
5163
SSL *clientssl = NULL, *serverssl = NULL;
5264
int ret = 1;
53-
size_t i;
5465
OSSL_TIME time;
5566
SSL_CTX *lsctx = NULL;
5667
SSL_CTX *lcctx = NULL;
@@ -96,7 +107,6 @@ static void do_handshake_ossl_lib_ctx_per_thread(size_t num)
96107
{
97108
SSL *clientssl = NULL, *serverssl = NULL;
98109
int ret = 1;
99-
size_t i;
100110
OSSL_TIME time;
101111
OSSL_LIB_CTX *libctx = NULL;
102112
SSL_CTX *lsctx = NULL;
@@ -142,19 +152,25 @@ static void do_handshake_ossl_lib_ctx_per_thread(size_t num)
142152
OSSL_LIB_CTX_free(libctx);
143153
}
144154

145-
static void do_handshake_ossl_lib_ctx_pool(size_t num)
155+
static void do_handshake_ctx_pool(size_t num)
146156
{
147157
SSL *clientssl = NULL, *serverssl = NULL;
148158
int ret = 1;
149-
size_t i;
150159
OSSL_TIME time;
151-
OSSL_LIB_CTX *libctx = NULL;
152160
SSL_CTX *lsctx = NULL;
153161
SSL_CTX *lcctx = NULL;
162+
struct ctxs *ctx = NULL;
154163

155-
libctx = libctx_pool[num % ossl_lib_ctx_pool_size];
156-
if (share_ctx == 1) {
157-
if (!perflib_create_ossl_lib_ctx_pair(libctx,
164+
ctx = ctx_pool[num % pool_size];
165+
166+
if (test_case == TC_SSL_CTX_POOL) {
167+
/* Use pre-created SSL_CTX from the pool */
168+
lsctx = ctx->sctx;
169+
lcctx = ctx->cctx;
170+
}
171+
172+
if (share_ctx == 1 && test_case == TC_OSSL_LIB_CTX_POOL) {
173+
if (!perflib_create_ossl_lib_ctx_pair(ctx->libctx,
158174
TLS_server_method(),
159175
TLS_client_method(),
160176
0, 0, &lsctx, &lcctx, cert,
@@ -168,8 +184,8 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
168184
counts[num] = 0;
169185

170186
do {
171-
if (share_ctx == 0) {
172-
if (!perflib_create_ossl_lib_ctx_pair(libctx,
187+
if (share_ctx == 0 && test_case == TC_OSSL_LIB_CTX_POOL) {
188+
if (!perflib_create_ossl_lib_ctx_pair(ctx->libctx,
173189
TLS_server_method(),
174190
TLS_client_method(),
175191
0, 0, &lsctx, &lcctx, cert,
@@ -186,7 +202,7 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
186202
SSL_ERROR_NONE);
187203
perflib_shutdown_ssl_connection(serverssl, clientssl);
188204
serverssl = clientssl = NULL;
189-
if (share_ctx == 0) {
205+
if (share_ctx == 0 && test_case == TC_OSSL_LIB_CTX_POOL) {
190206
SSL_CTX_free(lsctx);
191207
SSL_CTX_free(lcctx);
192208
lsctx = lcctx = NULL;
@@ -196,7 +212,7 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
196212
}
197213
while (time.t < max_time.t);
198214

199-
if (share_ctx == 1) {
215+
if (share_ctx == 1 && test_case == TC_OSSL_LIB_CTX_POOL) {
200216
SSL_CTX_free(lsctx);
201217
SSL_CTX_free(lcctx);
202218
}
@@ -205,57 +221,98 @@ static void do_handshake_ossl_lib_ctx_pool(size_t num)
205221
err = 1;
206222
}
207223

208-
static int init_ossl_lib_ctx_pool()
224+
static void free_ctx_pool()
225+
{
226+
if (ctx_pool == NULL)
227+
return;
228+
for (int i = 0; i < pool_size; ++i) {
229+
if (ctx_pool[i]) {
230+
OSSL_LIB_CTX_free(ctx_pool[i]->libctx);
231+
SSL_CTX_free(ctx_pool[i]->sctx);
232+
SSL_CTX_free(ctx_pool[i]->cctx);
233+
OPENSSL_free(ctx_pool[i]);
234+
}
235+
}
236+
OPENSSL_free(ctx_pool);
237+
ctx_pool = NULL;
238+
}
239+
240+
static int init_ctx_pool(init_ctx init_ctx)
209241
{
210-
libctx_pool = OPENSSL_malloc(ossl_lib_ctx_pool_size * sizeof(*libctx_pool));
211-
if (libctx_pool == NULL)
212-
return 1;
242+
ctx_pool = OPENSSL_zalloc(pool_size * sizeof(*ctx_pool));
243+
if (ctx_pool == NULL) {
244+
fprintf(stderr, "%s:%d: Failed to allocate ssl ctx pool\n", __FILE__, __LINE__);
245+
return 0;
246+
}
213247

214-
for (int i = 0; i < ossl_lib_ctx_pool_size; ++i) {
215-
libctx_pool[i] = OSSL_LIB_CTX_new();
216-
if (libctx_pool[i] == NULL) {
248+
for (int i = 0; i < pool_size; ++i) {
249+
SSL_CTX *lsctx = NULL, *lcctx = NULL;
250+
struct ctxs *ctx = NULL;
251+
OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
252+
253+
if (libctx == NULL) {
217254
fprintf(stderr, "%s:%d: Failed to create ossl lib context\n", __FILE__, __LINE__);
218255
return 0;
219256
}
220-
}
221257

222-
return 1;
223-
}
258+
if (init_ctx == INIT_LIB_AND_SSL_CTX) {
259+
if (!perflib_create_ossl_lib_ctx_pair(libctx,
260+
TLS_server_method(),
261+
TLS_client_method(),
262+
0, 0, &lsctx, &lcctx, cert,
263+
privkey)) {
264+
fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__);
265+
OSSL_LIB_CTX_free(libctx);
266+
return 0;
267+
}
268+
}
224269

225-
static void free_ossl_lib_ctx_pool()
226-
{
227-
for (int i = 0; i < ossl_lib_ctx_pool_size; ++i) {
228-
OSSL_LIB_CTX_free(libctx_pool[i]);
270+
ctx = OPENSSL_zalloc(sizeof(*ctx));
271+
if (ctx == NULL) {
272+
OSSL_LIB_CTX_free(libctx);
273+
SSL_CTX_free(lsctx);
274+
SSL_CTX_free(lcctx);
275+
return 0;
276+
}
277+
278+
ctx->libctx = libctx;
279+
ctx->sctx = lsctx;
280+
ctx->cctx = lcctx;
281+
ctx_pool[i] = ctx;
229282
}
230283

231-
OPENSSL_free(libctx_pool);
284+
return 1;
232285
}
233286

234287
static int test_ossl_lib_ctx_pool(size_t threadcount, OSSL_TIME *duration)
235288
{
236289
int ret = 0;
237290

238-
ret = init_ossl_lib_ctx_pool();
291+
if (test_case == TC_SSL_CTX_POOL)
292+
ret = init_ctx_pool(INIT_LIB_AND_SSL_CTX);
293+
else
294+
ret = init_ctx_pool(INIT_LIB_CTX);
239295
if (!ret)
240296
goto err;
241297

242-
ret = perflib_run_multi_thread_test(do_handshake_ossl_lib_ctx_pool, threadcount, duration);
298+
ret = perflib_run_multi_thread_test(do_handshake_ctx_pool, threadcount, duration);
243299
if (!ret)
244300
printf("Failed to run the test\n");
245301

246302
err:
247-
free_ossl_lib_ctx_pool();
303+
free_ctx_pool();
248304

249305
return ret;
250-
}
306+
}
251307

252308
void usage(const char *progname)
253309
{
254-
printf("Usage: %s [-t] [-s] [-p] [-P] [-o] certsdir threadcount\n", progname);
310+
printf("Usage: %s [options] certsdir threadcount\n", progname);
255311
printf("-t - terse output\n");
256312
printf("-s - disable context sharing\n");
257313
printf("-p - use ossl_lib_ctx per thread\n");
258314
printf("-P - use ossl_lib_ctx pool\n");
315+
printf("-l - use ssl ctx pool\n");
259316
printf("-o - set ossl_lib_ctx pool size\n");
260317
}
261318

@@ -269,11 +326,10 @@ int main(int argc, char * const argv[])
269326
int i;
270327
int terse = 0;
271328
int opt;
272-
int p_flag = 0, P_flag = 0;
329+
int p_flag = 0, P_flag = 0, l_flag = 0;
273330
char *endptr = NULL;
274-
test_case_t test_case = TC_SSL_CTX;
275331

276-
while ((opt = getopt(argc, argv, "tspPo:")) != -1) {
332+
while ((opt = getopt(argc, argv, "tspPo:l")) != -1) {
277333
switch (opt) {
278334
case 't':
279335
terse = 1;
@@ -291,8 +347,8 @@ int main(int argc, char * const argv[])
291347
break;
292348
case 'o':
293349
errno = 0;
294-
ossl_lib_ctx_pool_size = strtol(optarg, &endptr, 0);
295-
if (errno == ERANGE && ossl_lib_ctx_pool_size == ULONG_MAX) {
350+
pool_size = strtol(optarg, &endptr, 0);
351+
if (errno == ERANGE && pool_size == ULONG_MAX) {
296352
perror("Overflow occurred");
297353
usage(basename(argv[0]));
298354
return EXIT_FAILURE;
@@ -302,21 +358,25 @@ int main(int argc, char * const argv[])
302358
usage(basename(argv[0]));
303359
return EXIT_FAILURE;
304360
}
305-
if (ossl_lib_ctx_pool_size < 1) {
361+
if (pool_size < 1) {
306362
fprintf(stderr, "Pool size must be a > 0\n");
307363
usage(basename(argv[0]));
308364
return EXIT_FAILURE;
309365
}
310366
break;
367+
case 'l':
368+
l_flag = 1;
369+
test_case = TC_SSL_CTX_POOL;
370+
break;
311371
default:
312372
usage(basename(argv[0]));
313373
return EXIT_FAILURE;
314374
}
315375
}
316376

317-
if ((p_flag + P_flag) > 1) {
318-
fprintf(stderr,
319-
"Error: -p and -P mutually exclusive. Choose only one.\n\n");
377+
if ((p_flag + P_flag + l_flag) > 1) {
378+
fprintf(stderr, "Error: -p, -P, and -l are mutually exclusive."
379+
" Choose only one.\n\n");
320380
usage(basename(argv[0]));
321381
return EXIT_FAILURE;
322382
}
@@ -367,18 +427,16 @@ int main(int argc, char * const argv[])
367427
break;
368428
}
369429
case TC_OSSL_LIB_CTX_PER_THREAD: {
370-
ret =
371-
perflib_run_multi_thread_test(do_handshake_ossl_lib_ctx_per_thread,
372-
threadcount, &duration);
373-
if (!ret) {
430+
if (!perflib_run_multi_thread_test(do_handshake_ossl_lib_ctx_per_thread,
431+
threadcount, &duration)) {
374432
printf("Failed to run the test\n");
375433
goto err;
376434
}
377435
break;
378436
}
437+
case TC_SSL_CTX_POOL:
379438
case TC_OSSL_LIB_CTX_POOL: {
380-
int ret = test_ossl_lib_ctx_pool(threadcount, &duration);
381-
if (!ret) {
439+
if (!test_ossl_lib_ctx_pool(threadcount, &duration)) {
382440
printf("Failed to run the test\n");
383441
goto err;
384442
}

0 commit comments

Comments
 (0)