Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion cmake/functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,10 @@ function(generate_lib_src_list LIB_SOURCES)

if(BUILD_AESNI)
list(APPEND LIB_SOURCES wolfcrypt/src/aes_asm.S)
# 32-bit x86 AES-XTS. The file guards its own contents on
# WOLFSSL_AES_XTS and WOLFSSL_X86_BUILD, so it compiles to
# nothing on any other target or without XTS.
list(APPEND LIB_SOURCES wolfcrypt/src/aes_xts_x86_asm.S)

if(BUILD_INTELASM)
list(APPEND LIB_SOURCES wolfcrypt/src/aes_gcm_asm.S)
Expand Down Expand Up @@ -914,9 +918,13 @@ function(generate_lib_src_list LIB_SOURCES)
endif()

if(NOT BUILD_FIPS_V2 AND BUILD_AESNI)
# aes_xts_x86_asm.S guards its own contents on WOLFSSL_AES_XTS and
# WOLFSSL_X86_BUILD, so it compiles to nothing on any other target
# or without XTS.
list(APPEND LIB_SOURCES
wolfcrypt/src/aes_asm.S
wolfcrypt/src/aes_gcm_asm.S)
wolfcrypt/src/aes_gcm_asm.S
wolfcrypt/src/aes_xts_x86_asm.S)
endif()

if(BUILD_CAMELLIA)
Expand Down
16 changes: 10 additions & 6 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1215,10 +1215,13 @@ if (test "$host_cpu" = "x86_64" || test "$host_cpu" = "amd64") &&
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_X86_64_BUILD"
fi
if test "$host_cpu" = "x86"
then
# config.sub normalises 32-bit x86 to i386/i486/i586/i686, so matching only
# "x86" never fires for a real host triple.
case "$host_cpu" in
x86 | i?86)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_X86_BUILD"
fi
;;
esac


AC_ARG_ENABLE([leanpsk],
Expand Down Expand Up @@ -4801,11 +4804,12 @@ then
then
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_X86_64_BUILD"
fi
if test "$host_cpu" = "x86"
then
case "$host_cpu" in
x86 | i?86)
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_X86_BUILD"
ENABLED_X86_ASM=yes
fi
;;
esac
fi
AC_SUBST([ENABLED_AESNI])
AC_SUBST([ENABLED_AESNI_WITH_AVX])
Expand Down
85 changes: 72 additions & 13 deletions examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ static const char *wolfsentry_config_path = NULL;
#ifndef MAX_NON_BLOCK_SEC
#define MAX_NON_BLOCK_SEC 10
#endif
/* How long a single wait for the socket blocks before the loop re-checks its
* overall budget. Short enough that the budget is still honoured closely. */
#define NON_BLOCK_POLL_SEC 1

#define OCSP_STAPLING 1
#define OCSP_STAPLINGV2 2
Expand Down Expand Up @@ -1124,12 +1127,28 @@ static int ClientWrite(WOLFSSL* ssl, const char* msg, int msgSz, const char* str
return err;
}

static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
const char* str, int exitWithRet)
/* Read a reply. On a non-blocking socket a WANT_READ only means the reply has
* not arrived yet, so wait for it rather than returning on the first poll -
* returning early lets the caller shut the connection down while the peer is
* still writing, which the peer then reports as a transport error.
*
* replyRequired says whether a missing reply is a failure, not whether one is
* worth waiting for: it selects the wait budget and controls whether giving up
* is reported as an error. */
static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen,
int replyRequired, const char* str, int exitWithRet)
{
int ret, err;
char buffer[WOLFSSL_MAX_ERROR_SZ];
double start = current_time(1), elapsed;
/* A required reply gets the full non-blocking budget, an optional one the
* shorter of the two - MAX_NON_BLOCK_SEC is overridable and may be set
* below DEFAULT_TIMEOUT_SEC, which would otherwise invert the two. */
double maxWait = MAX_NON_BLOCK_SEC;

if (!replyRequired && DEFAULT_TIMEOUT_SEC < MAX_NON_BLOCK_SEC) {
maxWait = DEFAULT_TIMEOUT_SEC;
}

do {
err = 0; /* reset error */
Expand Down Expand Up @@ -1158,17 +1177,49 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
}
}

if (mustRead &&
(err == WOLFSSL_ERROR_WANT_READ
|| err == WOLFSSL_ERROR_WANT_WRITE)) {
if (err == WOLFSSL_ERROR_WANT_READ
|| err == WOLFSSL_ERROR_WANT_WRITE) {
int selectRet;

elapsed = current_time(0) - start;
if (elapsed > MAX_NON_BLOCK_SEC) {
LOG_ERROR("Nonblocking read timeout\n");
if (elapsed > maxWait) {
if (replyRequired) {
LOG_ERROR("Nonblocking read timeout\n");
}
ret = WOLFSSL_FATAL_ERROR;
break;
}

/* Wait for the socket instead of spinning on it. */
if (err == WOLFSSL_ERROR_WANT_WRITE) {
selectRet = tcp_select_tx(wolfSSL_get_fd(ssl),
NON_BLOCK_POLL_SEC);
}
else {
selectRet = tcp_select(wolfSSL_get_fd(ssl),
NON_BLOCK_POLL_SEC);
}

#ifdef WOLFSSL_DTLS
/* A DTLS timeout means the peer's datagram was lost - let the
* library retransmit rather than waiting for something that is
* never coming (see NonBlockingSSL_Connect). */
if (selectRet == TEST_TIMEOUT && wolfSSL_dtls(ssl)) {
if (wolfSSL_dtls_got_timeout(ssl) != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, WOLFSSL_FATAL_ERROR);
break;
}
}
else
#endif
/* select() itself failed - retrying would spin, not wait. */
if (selectRet == TEST_SELECT_FAIL) {
LOG_ERROR("%s tcp_select error\n", str);
ret = WOLFSSL_FATAL_ERROR;
break;
}
}
} while ((mustRead && err == WOLFSSL_ERROR_WANT_READ)
} while (err == WOLFSSL_ERROR_WANT_READ
|| err == WOLFSSL_ERROR_WANT_WRITE
#ifdef WOLFSSL_ASYNC_CRYPT
|| err == WC_NO_ERR_TRACE(WC_PENDING_E)
Expand All @@ -1183,11 +1234,15 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
return err;
}

/* replyRequired: whether a missing reply fails the exchange. See ClientRead. */
static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
char* reply, int replyLen, int mustRead,
char* reply, int replyLen, int replyRequired,
const char* str, int exitWithRet)
{
int ret = 0;
/* Which half of the exchange the error below came from - the message used
* to say SSL_write for a failure returned by ClientRead. */
const char* stage = "SSL_write";

do {
ret = ClientWrite(ssl, msg, msgSz, str, exitWithRet);
Expand All @@ -1207,15 +1262,17 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
}
else {
LOG_ERROR("%s tcp_select error\n", str);
stage = "tcp_select";
if (!exitWithRet)
err_sys("tcp_select failed");
else
ret = WOLFSSL_FATAL_ERROR;
break;
}
}
ret = ClientRead(ssl, reply, replyLen, mustRead, str, exitWithRet);
if (mustRead && ret != 0) {
stage = "SSL_read";
ret = ClientRead(ssl, reply, replyLen, replyRequired, str, exitWithRet);
if (replyRequired && ret != 0) {
if (!exitWithRet)
err_sys("ClientRead failed");
else
Expand All @@ -1224,9 +1281,11 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
break;
} while (1);

if (ret != 0) {
/* A failed optional read is not an error - the caller asked for the reply
* only if one turned up - so do not log one. */
if (ret != 0 && (replyRequired || XSTRCMP(stage, "SSL_read") != 0)) {
char buffer[WOLFSSL_MAX_ERROR_SZ];
LOG_ERROR("SSL_write%s msg error %d, %s\n", str, ret,
LOG_ERROR("%s%s msg error %d, %s\n", stage, str, ret,
wolfSSL_ERR_error_string((unsigned long)ret, buffer));
}

Expand Down
29 changes: 22 additions & 7 deletions scripts/benchmark.test
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,20 @@ if [ "$#" -lt 2 ]; then
exit 1
fi

# Use unique benchmark port so it won't conflict with any other tests
bench_port=11113
# Bind an ephemeral port and read it back from the ready file below, rather
# than hoping a fixed number is free. The ready file is per-run for the same
# reason - a fixed path is shared by any concurrent run.
bench_port=0
ready_file=/tmp/wolfssl_server_ready$$
no_pid=-1
server_pid=$no_pid
counter=0
client_result=-1

remove_ready_file() {
if test -e /tmp/wolfssl_server_ready; then
if test -e "$ready_file"; then
echo "removing existing server_ready file"
rm /tmp/wolfssl_server_ready
rm "$ready_file"
fi
}

Expand Down Expand Up @@ -96,27 +99,39 @@ remove_ready_file
if [ $1 -eq 1 ]
then
# start server in loop mode with port
./examples/server/server -i -p $bench_port $4 &
./examples/server/server -i -p $bench_port -R "$ready_file" $4 &
server_pid=$!
fi

# benchmark throughput
if [ $1 -eq 2 ]
then
# start server in loop mode, non-blocking, benchmark throughput with port
./examples/server/server -i -N -B $2 -p $bench_port $4 &
./examples/server/server -i -N -B $2 -p $bench_port -R "$ready_file" $4 &
server_pid=$!
fi

# NOTE: We sleep for 2 seconds below. If timing the execution of this script
# with "time", bear in mind that those 2 seconds will be reflected in
# the "real" time.
echo "Waiting for server_ready file..."
while [ ! -s /tmp/wolfssl_server_ready -a "$counter" -lt 20 ]; do
while [ ! -s "$ready_file" -a "$counter" -lt 20 ]; do
sleep 0.1
counter=$((counter+ 1))
done

if [ ! -s "$ready_file" ]; then
echo "Server never reported a port!"
do_cleanup
exit 1
fi

# sleep for an additional 0.1 to mitigate race on write/read of $ready_file:
sleep 0.1

bench_port=$(cat "$ready_file")
echo "Server listening on port $bench_port"

# benchmark connections
if [ $1 -eq 1 ]
then
Expand Down
Loading
Loading