Added throughput benchmarking for client/server examples and added helper script "scripts/benchmark.test". Added example client option: "-B <num>" Benchmarking throughput. Added example server options: "-B <num>" Benchmark throughput, "-e" Echo data, "-i" Loop / Accept multiple connections. Cleanup of the include.am for examples. Cleanup of tcp_connect with DTLS enabled. Cleanup of the valid socket checking. Cleanup trailing whitespace.

This commit is contained in:
David Garske
2015-10-14 19:13:45 -07:00
parent d6cb203210
commit fdab3943be
12 changed files with 700 additions and 328 deletions

View File

@@ -72,10 +72,7 @@ include support/include.am
include wolfcrypt/benchmark/include.am
include wolfcrypt/src/include.am
include wolfcrypt/test/include.am
include examples/client/include.am
include examples/server/include.am
include examples/echoclient/include.am
include examples/echoserver/include.am
include examples/include.am
include testsuite/include.am
include tests/include.am
include sslSniffer/sslSnifferTest/include.am

View File

@@ -127,6 +127,165 @@ static void ShowCiphers(void)
printf("%s\n", ciphers);
}
int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
int doDTLS, int benchmark, int resumeSession)
{
/* time passed in number of connects give average */
int times = benchmark;
int loops = resumeSession ? 2 : 1;
int i = 0;
WOLFSSL_SESSION* benchSession = NULL;
while (loops--) {
int benchResume = resumeSession && loops == 0;
double start = current_time(), avg;
for (i = 0; i < times; i++) {
SOCKET_T sockfd;
WOLFSSL* ssl = wolfSSL_new(ctx);
tcp_connect(&sockfd, host, port, doDTLS, ssl);
if (benchResume)
wolfSSL_set_session(ssl, benchSession);
wolfSSL_set_fd(ssl, sockfd);
if (wolfSSL_connect(ssl) != SSL_SUCCESS)
err_sys("SSL_connect failed");
wolfSSL_shutdown(ssl);
if (i == (times-1) && resumeSession) {
benchSession = wolfSSL_get_session(ssl);
}
wolfSSL_free(ssl);
CloseSocket(sockfd);
}
avg = current_time() - start;
avg /= times;
avg *= 1000; /* milliseconds */
if (benchResume)
printf("wolfSSL_resume avg took: %8.3f milliseconds\n", avg);
else
printf("wolfSSL_connect avg took: %8.3f milliseconds\n", avg);
}
return EXIT_SUCCESS;
}
int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
int doDTLS, int throughput)
{
double start, conn_time = 0, tx_time = 0, rx_time = 0;
SOCKET_T sockfd;
WOLFSSL* ssl;
int ret;
start = current_time();
ssl = wolfSSL_new(ctx);
tcp_connect(&sockfd, host, port, doDTLS, ssl);
wolfSSL_set_fd(ssl, sockfd);
if (wolfSSL_connect(ssl) == SSL_SUCCESS) {
/* Perform throughput test */
char *tx_buffer, *rx_buffer;
/* Record connection time */
conn_time = current_time() - start;
/* Allocate TX/RX buffers */
tx_buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
rx_buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(tx_buffer && rx_buffer) {
WC_RNG rng;
/* Startup the RNG */
ret = wc_InitRng(&rng);
if(ret == 0) {
int xfer_bytes;
/* Generate random data to send */
ret = wc_RNG_GenerateBlock(&rng, (byte*)tx_buffer, TEST_BUFFER_SIZE);
wc_FreeRng(&rng);
if(ret != 0) {
err_sys("wc_RNG_GenerateBlock failed");
}
/* Perform TX and RX of bytes */
xfer_bytes = 0;
while(throughput > xfer_bytes) {
int len, rx_pos;
/* Determine packet size */
len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes);
/* Perform TX */
start = current_time();
if (wolfSSL_write(ssl, tx_buffer, len) != len) {
int writeErr = wolfSSL_get_error(ssl, 0);
printf("wolfSSL_write error %d!\n", writeErr);
err_sys("wolfSSL_write failed");
}
tx_time += current_time() - start;
/* Perform RX */
int select_ret = tcp_select(sockfd, 1); /* Timeout=1 second */
if (select_ret == TEST_RECV_READY) {
start = current_time();
rx_pos = 0;
while(rx_pos < len) {
ret = wolfSSL_read(ssl, &rx_buffer[rx_pos], len - rx_pos);
if(ret <= 0) {
int readErr = wolfSSL_get_error(ssl, 0);
if (readErr != SSL_ERROR_WANT_READ) {
printf("wolfSSL_read error %d!\n", readErr);
err_sys("wolfSSL_read failed");
}
}
else {
rx_pos += ret;
}
}
rx_time += current_time() - start;
}
/* Compare TX and RX buffers */
if(XMEMCMP(tx_buffer, rx_buffer, len) != 0) {
err_sys("Compare TX and RX buffers failed");
}
/* Update overall position */
xfer_bytes += len;
}
}
else {
err_sys("wc_InitRng failed");
}
}
else {
err_sys("Buffer alloc failed");
}
if(tx_buffer) XFREE(tx_buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(rx_buffer) XFREE(rx_buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
else {
err_sys("wolfSSL_connect failed");
}
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
CloseSocket(sockfd);
printf("wolfSSL Client Benchmark %d bytes\n"
"\tConnect %8.3f ms\n"
"\tTX %8.3f ms (%8.3f MBps)\n"
"\tRX %8.3f ms (%8.3f MBps)\n",
throughput,
conn_time * 1000,
tx_time * 1000, throughput / tx_time / 1024 / 1024,
rx_time * 1000, throughput / rx_time / 1024 / 1024
);
return EXIT_SUCCESS;
}
static void Usage(void)
{
@@ -137,7 +296,7 @@ static void Usage(void)
printf("-p <num> Port to connect on, not 0, default %d\n", wolfSSLPort);
printf("-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
CLIENT_DEFAULT_VERSION);
printf("-l <str> Cipher list\n");
printf("-l <str> Cipher suite list (: delimited)\n");
printf("-c <file> Certificate file, default %s\n", cliCert);
printf("-k <file> Key file, default %s\n", cliKey);
printf("-A <file> Certificate Authority file, default %s\n", caCert);
@@ -149,6 +308,7 @@ static void Usage(void)
#ifdef HAVE_ALPN
printf("-L <str> Application-Layer Protocole Name ({C,F}:<list>)\n");
#endif
printf("-B <num> Benchmark throughput using <num> bytes and print stats\n");
printf("-s Use pre Shared keys\n");
printf("-t Track wolfSSL memory use\n");
printf("-d Disable peer checks\n");
@@ -156,7 +316,7 @@ static void Usage(void)
printf("-e List Every cipher suite available, \n");
printf("-g Send server HTTP GET\n");
printf("-u Use UDP DTLS,"
" add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2\n");
" add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n");
printf("-m Match domain name in cert\n");
printf("-N Use Non-blocking sockets\n");
printf("-r Resume session\n");
@@ -200,7 +360,7 @@ static void Usage(void)
THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
{
SOCKET_T sockfd = 0;
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
WOLFSSL_METHOD* method = 0;
WOLFSSL_CTX* ctx = 0;
@@ -228,6 +388,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
int useAnon = 0;
int sendGET = 0;
int benchmark = 0;
int throughput = 0;
int doDTLS = 0;
int matchName = 0;
int doPeerCheck = 1;
@@ -300,7 +461,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
StackTrap();
while ((ch = mygetopt(argc, argv,
"?gdeDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:an:"))
"?gdeDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:an:B:"))
!= -1) {
switch (ch) {
case '?' :
@@ -426,6 +587,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
break;
case 'B' :
throughput = atoi(myoptarg);
if (throughput <= 0) {
Usage();
exit(MY_EX_USAGE);
}
break;
case 'N' :
nonBlocking = 1;
break;
@@ -633,9 +802,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (ctx == NULL)
err_sys("unable to get ctx");
if (cipherList)
if (cipherList) {
if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
err_sys("client can't set cipher list 1");
}
#ifdef WOLFSSL_LEANPSK
usePsk = 1;
@@ -770,45 +940,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif
if (benchmark) {
/* time passed in number of connects give average */
int times = benchmark;
int loops = resumeSession ? 2 : 1;
int i = 0;
WOLFSSL_SESSION* benchSession = NULL;
while (loops--) {
int benchResume = resumeSession && loops == 0;
double start = current_time(), avg;
for (i = 0; i < times; i++) {
tcp_connect(&sockfd, host, port, doDTLS);
ssl = wolfSSL_new(ctx);
if (benchResume)
wolfSSL_set_session(ssl, benchSession);
wolfSSL_set_fd(ssl, sockfd);
if (wolfSSL_connect(ssl) != SSL_SUCCESS)
err_sys("SSL_connect failed");
wolfSSL_shutdown(ssl);
if (i == (times-1) && resumeSession) {
benchSession = wolfSSL_get_session(ssl);
}
wolfSSL_free(ssl);
CloseSocket(sockfd);
}
avg = current_time() - start;
avg /= times;
avg *= 1000; /* milliseconds */
if (benchResume)
printf("wolfSSL_resume avg took: %8.3f milliseconds\n", avg);
else
printf("wolfSSL_connect avg took: %8.3f milliseconds\n", avg);
}
((func_args*)args)->return_code =
ClientBenchmarkConnections(ctx, host, port, doDTLS, benchmark, resumeSession);
wolfSSL_CTX_free(ctx);
((func_args*)args)->return_code = 0;
exit(EXIT_SUCCESS);
}
if(throughput) {
((func_args*)args)->return_code =
ClientBenchmarkThroughput(ctx, host, port, doDTLS, throughput);
wolfSSL_CTX_free(ctx);
exit(EXIT_SUCCESS);
}
@@ -830,15 +971,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
#endif
if (doDTLS) {
SOCKADDR_IN_T addr;
build_addr(&addr, host, port, 1);
wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
tcp_socket(&sockfd, 1);
}
else {
tcp_connect(&sockfd, host, port, 0);
}
tcp_connect(&sockfd, host, port, doDTLS, ssl);
#ifdef HAVE_POLY1305
/* use old poly to connect with google and wolfssl.com server */
@@ -986,21 +1119,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifndef NO_SESSION_CACHE
if (resumeSession) {
if (doDTLS) {
SOCKADDR_IN_T addr;
#ifdef USE_WINDOWS_API
#ifdef USE_WINDOWS_API
Sleep(500);
#elif defined(WOLFSSL_TIRTOS)
#elif defined(WOLFSSL_TIRTOS)
Task_sleep(1);
#else
#else
sleep(1);
#endif
build_addr(&addr, host, port, 1);
wolfSSL_dtls_set_peer(sslResume, &addr, sizeof(addr));
tcp_socket(&sockfd, 1);
}
else {
tcp_connect(&sockfd, host, port, 0);
#endif
}
tcp_connect(&sockfd, host, port, doDTLS, sslResume);
wolfSSL_set_fd(sslResume, sockfd);
#ifdef HAVE_ALPN
if (alpnList != NULL) {

View File

@@ -23,3 +23,11 @@
THREAD_RETURN WOLFSSL_THREAD client_test(void* args);
/* Measures average time to create, connect and disconnect a connection (TPS).
Benchmark = number of connections. */
int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
int doDTLS, int benchmark, int resumeSession);
/* Measures throughput in kbps. Throughput = number of bytes */
int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
int doDTLS, int throughput);

View File

@@ -164,16 +164,7 @@ void echoclient_test(void* args)
#endif
ssl = SSL_new(ctx);
if (doDTLS) {
SOCKADDR_IN_T addr;
build_addr(&addr, yasslIP, port, 1);
CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
tcp_socket(&sockfd, 1);
}
else {
tcp_connect(&sockfd, yasslIP, port, 0);
}
tcp_connect(&sockfd, yasslIP, port, doDTLS, ssl);
SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)

View File

@@ -248,7 +248,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
err_sys("recvfrom failed");
}
#endif
if (clientfd == -1) err_sys("tcp accept failed");
if (WOLFSSL_SOCKET_IS_INVALID(clientfd)) err_sys("tcp accept failed");
ssl = CyaSSL_new(ctx);
if (ssl == NULL) err_sys("SSL_new failed");

7
examples/include.am Normal file
View File

@@ -0,0 +1,7 @@
# vim:ft=automake
# All paths should be given relative to the root
include examples/client/include.am
include examples/echoclient/include.am
include examples/echoserver/include.am
include examples/server/include.am

View File

@@ -81,10 +81,11 @@ static void NonBlockingSSL_Accept(SSL* ssl)
error == SSL_ERROR_WANT_WRITE)) {
int currTimeout = 1;
if (error == SSL_ERROR_WANT_READ)
printf("... server would read block\n");
else
printf("... server would write block\n");
if (error == SSL_ERROR_WANT_READ) {
/* printf("... server would read block\n"); */
} else {
/* printf("... server would write block\n"); */
}
#ifdef CYASSL_DTLS
currTimeout = CyaSSL_dtls_get_current_timeout(ssl);
@@ -118,6 +119,68 @@ static void NonBlockingSSL_Accept(SSL* ssl)
err_sys("SSL_accept failed");
}
/* Echo number of bytes specified by -e arg */
int ServerEchoData(SSL* ssl, int clientfd, int echoData, int throughput)
{
int ret = 0;
char* buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(buffer) {
double start, rx_time = 0, tx_time = 0;
int xfer_bytes = 0;
while((echoData && throughput == 0) || (!echoData && xfer_bytes < throughput)) {
int select_ret = tcp_select(clientfd, 1); /* Timeout=1 second */
if (select_ret == TEST_RECV_READY) {
int len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes);
int rx_pos = 0;
if(throughput) {
start = current_time();
}
while(rx_pos < len) {
ret = SSL_read(ssl, &buffer[rx_pos], len - rx_pos);
if (ret <= 0) {
int readErr = SSL_get_error(ssl, 0);
if (readErr != SSL_ERROR_WANT_READ) {
printf("SSL_read error %d!\n", readErr);
err_sys("SSL_read failed");
}
}
else {
rx_pos += ret;
}
}
if(throughput) {
rx_time += current_time() - start;
start = current_time();
}
if (SSL_write(ssl, buffer, len) != len) {
err_sys("SSL_write failed");
}
if(throughput) {
tx_time += current_time() - start;
}
xfer_bytes += len;
}
}
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if(throughput) {
printf("wolfSSL Server Benchmark %d bytes\n"
"\tRX %8.3f ms (%8.3f MBps)\n"
"\tTX %8.3f ms (%8.3f MBps)\n",
throughput,
tx_time * 1000, throughput / tx_time / 1024 / 1024,
rx_time * 1000, throughput / rx_time / 1024 / 1024
);
}
}
else {
err_sys("Server buffer XMALLOC failed");
}
return EXIT_SUCCESS;
}
static void Usage(void)
{
@@ -127,7 +190,7 @@ static void Usage(void)
printf("-p <num> Port to listen on, not 0, default %d\n", yasslPort);
printf("-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
SERVER_DEFAULT_VERSION);
printf("-l <str> Cipher list\n");
printf("-l <str> Cipher suite list (: delimited)\n");
printf("-c <file> Certificate file, default %s\n", svrCert);
printf("-k <file> Key file, default %s\n", svrKey);
printf("-A <file> Certificate Authority file, default %s\n", cliCert);
@@ -144,7 +207,7 @@ static void Usage(void)
printf("-s Use pre Shared keys\n");
printf("-t Track wolfSSL memory use\n");
printf("-u Use UDP DTLS,"
" add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2\n");
" add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n");
printf("-f Fewer packets/group messages\n");
printf("-R Create server ready file, for external monitor\n");
printf("-r Allow one client Resumption\n");
@@ -164,20 +227,22 @@ static void Usage(void)
#ifndef NO_PSK
printf("-I Do not send PSK identity hint\n");
#endif
printf("-i Loop indefinitely (allow repeated connections)\n");
printf("-e Echo data mode (return raw bytes received)\n");
printf("-B <num> Benchmark throughput using <num> bytes and print stats\n");
}
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
SOCKET_T sockfd = 0;
SOCKET_T clientfd = 0;
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
SSL_METHOD* method = 0;
SSL_CTX* ctx = 0;
SSL* ssl = 0;
char msg[] = "I hear you fa shizzle!";
const char msg[] = "I hear you fa shizzle!";
char input[80];
int idx;
int ch;
int version = SERVER_DEFAULT_VERSION;
int doCliCertCheck = 1;
@@ -194,8 +259,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
int pkCallbacks = 0;
int serverReadyFile = 0;
int wc_shutdown = 0;
int resume = 0; /* do resume, and resume count */
int resume = 0;
int resumeCount = 0;
int loopIndefinitely = 0;
int echoData = 0;
int throughput;
int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
int doListen = 1;
int ret;
char* alpnList = NULL;
unsigned char alpn_opt = 0;
@@ -244,7 +314,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
fdOpenSession(Task_self());
#endif
while ((ch = mygetopt(argc, argv, "?dbstnNufrRawPIp:v:l:A:c:k:Z:S:oO:D:L:"))
while ((ch = mygetopt(argc, argv, "?dbstnNufrRawPIp:v:l:A:c:k:Z:S:oO:D:L:ieB:"))
!= -1) {
switch (ch) {
case '?' :
@@ -400,6 +470,23 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#endif
break;
case 'i' :
loopIndefinitely = 1;
break;
case 'e' :
echoData = 1;
break;
case 'B':
throughput = atoi(myoptarg);
if (throughput <= 0) {
Usage();
exit(MY_EX_USAGE);
}
break;
default:
Usage();
exit(MY_EX_USAGE);
@@ -593,8 +680,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
err_sys("UseSNI failed");
#endif
while (1) { /* allow resume option */
if (resume > 1) { /* already did listen, just do accept */
while (1) {
/* allow resume option */
if(resumeCount > 1) {
if (doDTLS == 0) {
SOCKADDR_IN_T client;
socklen_t client_len = sizeof(client);
@@ -604,11 +692,10 @@ while (1) { /* allow resume option */
tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
clientfd = sockfd;
}
#ifdef USE_WINDOWS_API
if (clientfd == INVALID_SOCKET) err_sys("tcp accept failed");
#else
if (clientfd == -1) err_sys("tcp accept failed");
#endif
if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
err_sys("tcp accept failed");
}
resumeCount = 0;
}
ssl = SSL_new(ctx);
@@ -640,10 +727,10 @@ while (1) { /* allow resume option */
SetupPkCallbacks(ctx, ssl);
#endif
if (resume < 2) { /* do listen and accept */
/* do accept */
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
doDTLS, serverReadyFile);
}
doDTLS, serverReadyFile, doListen);
doListen = 0; /* Don't listen next time */
SSL_set_fd(ssl, clientfd);
@@ -713,13 +800,14 @@ while (1) { /* allow resume option */
}
#endif
idx = SSL_read(ssl, input, sizeof(input)-1);
if (idx > 0) {
input[idx] = 0;
if(echoData == 0 && throughput == 0) {
ret = SSL_read(ssl, input, sizeof(input)-1);
if (ret > 0) {
input[ret] = 0;
printf("Client message: %s\n", input);
}
else if (idx < 0) {
else if (ret < 0) {
int readErr = SSL_get_error(ssl, 0);
if (readErr != SSL_ERROR_WANT_READ)
err_sys("SSL_read failed");
@@ -727,12 +815,16 @@ while (1) { /* allow resume option */
if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
err_sys("SSL_write failed");
}
else {
ServerEchoData(ssl, clientfd, echoData, throughput);
}
#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
os_dly_wait(500) ;
#elif defined (CYASSL_TIRTOS)
#elif defined (CYASSL_TIRTOS)
Task_yield();
#endif
#endif
if (doDTLS == 0) {
ret = SSL_shutdown(ssl);
@@ -740,17 +832,22 @@ while (1) { /* allow resume option */
SSL_shutdown(ssl); /* bidirectional shutdown */
}
SSL_free(ssl);
if (resume == 1) {
CloseSocket(clientfd);
resume++; /* only do one resume for testing */
continue;
}
break; /* out of while loop, done with normal and resume option */
}
SSL_CTX_free(ctx);
CloseSocket(clientfd);
if (resume == 1) {
resumeCount++; /* only do one resume for testing */
continue;
}
if(!loopIndefinitely) {
break; /* out of while loop, done with normal and resume option */
}
} /* while(1) */
CloseSocket(sockfd);
SSL_CTX_free(ctx);
((func_args*)args)->return_code = 0;

View File

@@ -22,3 +22,7 @@
#pragma once
THREAD_RETURN WOLFSSL_THREAD server_test(void* args);
/* Echo bytes using buffer of TEST_BUFFER_SIZE until [echoData] bytes are complete. */
/* If [bechmarkThroughput] set the statistcs will be output at the end */
int ServerEchoData(WOLFSSL* ssl, int clientfd, int echoData, int benchmarkThroughput);

115
scripts/benchmark.test Executable file
View File

@@ -0,0 +1,115 @@
#!/bin/sh
#benchmark.test
if [ "$#" -lt 2 ]; then
echo "Usage: $0 [mode] [num] [clientargs] [serverargs]" >&2
echo " [mode]: 1=Connection Rate (TPS), 2=Throughput Bytes" >&2
echo " [num]: Mode 1=Connection Count, Mode 2=Bytes to TX/RX" >&2
echo " [clientargs]: Passed to client (see \"./example/client/client -?\" for help)" >&2
echo " Example: Use different cipher suite: \"-l DHE-RSA-AES256-SHA\"" >&2
echo " [serverargs]: Passed to server (see \"./example/server/server -?\" for help)" >&2
echo " Example: Disable client certificate check: \"-d\"" >&2
echo "Note: If additional client or server args contains spaces wrap with double quotes" >&2
exit 1
fi
# Use unique benchmark port so it won't conflict with any other tests
bench_port=11113
no_pid=-1
server_pid=$no_pid
counter=0
client_result=-1
remove_ready_file() {
if test -e /tmp/wolfssl_server_ready; then
echo "removing exisitng server_ready file"
rm /tmp/wolfssl_server_ready
fi
}
do_cleanup() {
echo "in cleanup"
if [ $server_pid != $no_pid ]
then
echo "killing server"
kill -9 $server_pid
fi
remove_ready_file
}
do_trap() {
echo "got trap"
do_cleanup
exit -1
}
trap do_trap INT TERM
# Start server in loop continuous mode (-L) with echo data (-e) enabled and non-blocking (-N)
echo "\nStarting example server for benchmark test"
remove_ready_file
# benchmark connections
if [ $1 == 1 ]
then
# start server in loop mode with port
./examples/server/server -i -p $bench_port $4 &
server_pid=$!
fi
# benchmark throughput
if [ $1 == 2 ]
then
# start server in loop mode, non-blocking, benchmark throughput with port
./examples/server/server -i -N -B $2 -p $bench_port $4 &
server_pid=$!
fi
echo "Waiting for server_ready file..."
while [ ! -s /tmp/wolfssl_server_ready -a "$counter" -lt 20 ]; do
sleep 0.1
counter=$((counter+ 1))
done
# benchmark connections
if [ $1 == 1 ]
then
echo "Starting example client to benchmark connection average time"
# start client to benchmark average time for each connection using port
./examples/client/client -b $2 -p $bench_port $3
client_result=$?
fi
# benchmark throughput
if [ $1 == 2 ]
then
echo "Starting example client to benchmark throughput"
# start client in non-blocking mode, benchmark throughput using port
./examples/client/client -N -B $2 -p $bench_port $3
client_result=$?
fi
if [ $client_result != 0 ]
then
echo "Client failed!"
do_cleanup
exit 1
fi
# End server
kill -6 $server_pid
server_result=$?
remove_ready_file
if [ $server_result != 0 ]
then
echo "Server failed!"
exit 1
fi
echo "\nSuccess!\n"
exit 0

View File

@@ -10,6 +10,7 @@ endif
if BUILD_EXAMPLES
dist_noinst_SCRIPTS+= scripts/resume.test
EXTRA_DIST+= scripts/benchmark.test
if BUILD_CRL
# make revoked test rely on completion of resume test

View File

@@ -357,7 +357,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
}
ssl = wolfSSL_new(ctx);
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0);
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 1);
CloseSocket(sockfd);
wolfSSL_set_fd(ssl, clientfd);
@@ -467,9 +467,8 @@ static void test_client_nofail(void* args)
goto done2;
}
tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, 0);
ssl = wolfSSL_new(ctx);
tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl);
wolfSSL_set_fd(ssl, sockfd);
if (wolfSSL_connect(ssl) != SSL_SUCCESS)
{
@@ -557,7 +556,7 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
ssl = wolfSSL_new(ctx);
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0);
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 1);
CloseSocket(sfd);
wolfSSL_set_fd(ssl, cfd);
@@ -650,9 +649,8 @@ static void run_wolfssl_client(void* args)
if (callbacks->ctx_ready)
callbacks->ctx_ready(ctx);
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0);
ssl = wolfSSL_new(ctx);
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl);
wolfSSL_set_fd(ssl, sfd);
if (callbacks->ssl_ready)

View File

@@ -118,6 +118,39 @@
#pragma warning(disable:4244 4996)
#endif
/* Buffer for benchmark tests */
#ifndef TEST_BUFFER_SIZE
#define TEST_BUFFER_SIZE 16384
#endif
#ifndef WOLFSSL_HAVE_MIN
#define WOLFSSL_HAVE_MIN
static INLINE word32 min(word32 a, word32 b)
{
return a > b ? b : a;
}
#endif /* WOLFSSL_HAVE_MIN */
/* Socket Handling */
#ifndef WOLFSSL_SOCKET_INVALID
#ifdef USE_WINDOWS_API
#define WOLFSSL_SOCKET_INVALID INVALID_SOCKET
#elif defined(WOLFSSL_TIRTOS)
#define WOLFSSL_SOCKET_INVALID -1
#else
#define WOLFSSL_SOCKET_INVALID 0
#endif
#endif /* WOLFSSL_SOCKET_INVALID */
#ifndef WOLFSSL_SOCKET_IS_INVALID
#ifdef USE_WINDOWS_API
#define WOLFSSL_SOCKET_IS_INVALID(s) ((s) == WOLFSSL_SOCKET_INVALID)
#elif defined(WOLFSSL_TIRTOS)
#define WOLFSSL_SOCKET_IS_INVALID(s) ((s) == WOLFSSL_SOCKET_INVALID)
#else
#define WOLFSSL_SOCKET_IS_INVALID(s) ((s) < WOLFSSL_SOCKET_INVALID)
#endif
#endif /* WOLFSSL_SOCKET_IS_INVALID */
#if defined(__MACH__) || defined(USE_WINDOWS_API)
#ifndef _SOCKLEN_T
@@ -542,16 +575,9 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, int udp)
else
*sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
#ifdef USE_WINDOWS_API
if (*sockfd == INVALID_SOCKET)
if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
err_sys("socket failed\n");
#elif defined(WOLFSSL_TIRTOS)
if (*sockfd == -1)
err_sys("socket failed\n");
#else
if (*sockfd < 0)
err_sys("socket failed\n");
#endif
}
#ifndef USE_WINDOWS_API
#ifdef SO_NOSIGPIPE
@@ -583,10 +609,13 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, int udp)
}
static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
int udp)
int udp, WOLFSSL* ssl)
{
SOCKADDR_IN_T addr;
build_addr(&addr, ip, port, udp);
if(udp) {
wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
}
tcp_socket(sockfd, udp);
if (!udp) {
@@ -769,7 +798,7 @@ static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
func_args* args, word16 port, int useAnyAddr,
int udp, int ready_file)
int udp, int ready_file, int do_listen)
{
SOCKADDR_IN_T client;
socklen_t client_len = sizeof(client);
@@ -779,9 +808,10 @@ static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
return;
}
if(do_listen) {
tcp_listen(sockfd, &port, useAnyAddr, udp);
#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
/* signal ready to tcp_accept */
{
tcp_ready* ready = args->signal;
@@ -791,15 +821,15 @@ static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
pthread_cond_signal(&ready->cond);
pthread_mutex_unlock(&ready->mutex);
}
#elif defined (WOLFSSL_TIRTOS)
#elif defined (WOLFSSL_TIRTOS)
/* Need mutex? */
tcp_ready* ready = args->signal;
ready->ready = 1;
ready->port = port;
#endif
#endif
if (ready_file) {
#ifndef NO_FILESYSTEM
#ifndef NO_FILESYSTEM
#ifndef USE_WINDOWS_API
FILE* srf = fopen("/tmp/wolfssl_server_ready", "w");
#else
@@ -810,18 +840,15 @@ static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
fputs("ready", srf);
fclose(srf);
}
#endif
#endif
}
}
*clientfd = accept(*sockfd, (struct sockaddr*)&client,
(ACCEPT_THIRD_T)&client_len);
#ifdef USE_WINDOWS_API
if (*clientfd == INVALID_SOCKET)
if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
err_sys("tcp accept failed");
#else
if (*clientfd == -1)
err_sys("tcp accept failed");
#endif
}
}