diff options
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/benchmark-common.c | 133 | ||||
-rw-r--r-- | src/benchmark-tls.c | 189 | ||||
-rw-r--r-- | src/benchmark.c | 185 | ||||
-rw-r--r-- | src/benchmark.h | 22 | ||||
-rw-r--r-- | tests/eagain-common.h | 7 |
6 files changed, 372 insertions, 171 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 379d3c8f32..cc7881eb12 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ AM_CPPFLAGS = \ -I$(srcdir)/../libextra/includes \ -I$(srcdir)/cfg -noinst_PROGRAMS = benchmark +noinst_PROGRAMS = benchmark benchmark-tls bin_PROGRAMS = gnutls-serv gnutls-cli psktool gnutls-cli-debug if ENABLE_PKI bin_PROGRAMS += certtool p11tool @@ -65,9 +65,12 @@ noinst_LTLIBRARIES += libcmd-psk.la libcmd_psk_la_CFLAGS = libcmd_psk_la_SOURCES = psk.gaa psk-gaa.h psk-gaa.c -benchmark_SOURCES = benchmark.c +benchmark_SOURCES = benchmark.c benchmark-common.c benchmark.h benchmark_LDADD = ../lib/libgnutls.la ../gl/libgnu.la $(LIB_CLOCK_GETTIME) +benchmark_tls_SOURCES = benchmark-tls.c benchmark-common.c benchmark.h +benchmark_tls_LDADD = ../lib/libgnutls.la ../gl/libgnu.la $(LIB_CLOCK_GETTIME) + gnutls_cli_SOURCES = cli.c common.h common.c p11common.c p11common.h gnutls_cli_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la gnutls_cli_LDADD += libcmd-cli.la ../gl/libgnu.la diff --git a/src/benchmark-common.c b/src/benchmark-common.c new file mode 100644 index 0000000000..6e64747033 --- /dev/null +++ b/src/benchmark-common.c @@ -0,0 +1,133 @@ +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <sys/time.h> +#include <time.h> +#include <unistd.h> +#include "benchmark.h" + +int benchmark_must_finish = 0; + +#if !defined(_WIN32) +static void +alarm_handler (int signo) +{ + benchmark_must_finish = 1; +} +#else +#include <windows.h> +DWORD WINAPI +alarm_handler (LPVOID lpParameter) +{ + HANDLE wtimer = *((HANDLE *) lpParameter); + WaitForSingleObject (wtimer, INFINITE); + benchmark_must_finish = 1; + return 0; +} + +#define W32_ALARM_VARIABLES HANDLE wtimer = NULL, wthread = NULL; \ + LARGE_INTEGER alarm_timeout = { 0 , 0 } +#define W32_ALARM_TRIGGER(timeout, leave) { \ + wtimer = CreateWaitableTimer (NULL, TRUE, NULL); \ + if (wtimer == NULL) \ + { \ + fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ()); \ + leave; \ + } \ + wthread = CreateThread (NULL, 0, alarm_handler, &wtimer, 0, NULL); \ + if (wthread == NULL) \ + { \ + fprintf (stderr, "error: CreateThread %u\n", GetLastError ()); \ + leave; \ + } \ + alarm_timeout.QuadPart = timeout * 10000000; \ + if (SetWaitableTimer (wtimer, &alarm_timeout, 0, NULL, NULL, FALSE) == 0) \ + { \ + fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ()); \ + leave; \ + } \ + } +#define W32_ALARM_CLEANUP { \ + if (wtimer != NULL) \ + CloseHandle (wtimer); \ + if (wthread != NULL) \ + CloseHandle (wthread);} +#endif + +static void +value2human (unsigned long bytes, double time, double *data, double *speed, + char *metric) +{ + if (bytes > 1000 && bytes < 1000 * 1000) + { + *data = ((double) bytes) / 1000; + *speed = *data / time; + strcpy (metric, "Kb"); + return; + } + else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) + { + *data = ((double) bytes) / (1000 * 1000); + *speed = *data / time; + strcpy (metric, "Mb"); + return; + } + else if (bytes >= 1000 * 1000 * 1000) + { + *data = ((double) bytes) / (1000 * 1000 * 1000); + *speed = *data / time; + strcpy (metric, "Gb"); + return; + } + else + { + *data = (double) bytes; + *speed = *data / time; + strcpy (metric, "bytes"); + return; + } +} + +void start_benchmark(struct benchmark_st * st) +{ + st->old_handler = signal (SIGALRM, alarm_handler); + + benchmark_must_finish = 0; + st->size = 0; + +#if !defined(_WIN32) + alarm (5); +#else + W32_ALARM_TRIGGER(5, goto leave); +#endif + gettime (&st->start); + +} + +/* returns the elapsed time */ +double stop_benchmark(struct benchmark_st * st) +{ + double secs; + struct timespec stop; + double dspeed, ddata; + char metric[16]; + +#if defined(_WIN32) +leave: + W32_ALARM_CLEANUP; +#else + signal(SIGALRM, st->old_handler); +#endif + + gettime (&stop); + + secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - + (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000))); + secs /= 1000; + + value2human (st->size, secs, &ddata, &dspeed, metric); + printf ("Processed %.2f %s in %.2f secs: ", ddata, metric, secs); + printf ("%.2f %s/sec\n", dspeed, metric); + + return secs; +} diff --git a/src/benchmark-tls.c b/src/benchmark-tls.c new file mode 100644 index 0000000000..cc0c7a1341 --- /dev/null +++ b/src/benchmark-tls.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS. + * + * GnuTLS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <gnutls/gnutls.h> +#include <gnutls/crypto.h> + +#define fail(...) \ + { \ + fprintf(stderr, __VA_ARGS__); \ + exit(1); \ + } + +#include "../tests/eagain-common.h" +#include "benchmark.h" + +#define PRIO_AES_CBC_SHA1 "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH" +#define PRIO_CAMELLIA_CBC_SHA1 "NONE:+VERS-TLS1.0:+CAMELLIA-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH" + +const char *pkcs3 = + "-----BEGIN DH PARAMETERS-----\n" + "MIGGAoGAtkxw2jlsVCsrfLqxrN+IrF/3W8vVFvDzYbLmxi2GQv9s/PQGWP1d9i22\n" + "P2DprfcJknWt7KhCI1SaYseOQIIIAYP78CfyIpGScW/vS8khrw0rlQiyeCvQgF3O\n" + "GeGOEywcw+oQT4SmFOD7H0smJe2CNyjYpexBXQ/A0mbTF9QKm1cCAQU=\n" + "-----END DH PARAMETERS-----\n"; + +char buffer[64 * 1024]; + +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "|<%d>| %s", level, str); +} + +static void +test_ciphersuite (const char* cipher_prio, int size) +{ + /* Server stuff. */ + gnutls_anon_server_credentials_t s_anoncred; + const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; + static gnutls_dh_params_t dh_params; + gnutls_session_t server; + int sret, cret; + const char *str; + /* Client stuff. */ + gnutls_anon_client_credentials_t c_anoncred; + gnutls_session_t client; + /* Need to enable anonymous KX specifically. */ + int ret; + struct benchmark_st st; + + /* Init server */ + gnutls_anon_allocate_server_credentials (&s_anoncred); + gnutls_dh_params_init (&dh_params); + gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM); + gnutls_anon_set_server_dh_params (s_anoncred, dh_params); + gnutls_init (&server, GNUTLS_SERVER); + ret = gnutls_priority_set_direct (server, cipher_prio, &str); + if (ret < 0) + { + fprintf (stderr, "Error in %s\n", str); + exit (1); + } + gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred); + gnutls_dh_set_prime_bits (server, 1024); + gnutls_transport_set_push_function (server, server_push); + gnutls_transport_set_pull_function (server, server_pull); + gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t) server); + reset_buffers(); + + /* Init client */ + gnutls_anon_allocate_client_credentials (&c_anoncred); + gnutls_init (&client, GNUTLS_CLIENT); + + ret = gnutls_priority_set_direct (client, cipher_prio, &str); + if (ret < 0) + { + fprintf (stderr, "Error in %s\n", str); + exit (1); + } + gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred); + gnutls_transport_set_push_function (client, client_push); + gnutls_transport_set_pull_function (client, client_pull); + gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t) client); + + HANDSHAKE (client, server); + + fprintf (stdout, "Testing %s with %d packet size: ", + gnutls_cipher_suite_get_name(gnutls_kx_get(server), + gnutls_cipher_get(server), gnutls_mac_get(server)), size); + fflush (stdout); + + gnutls_rnd (GNUTLS_RND_NONCE, buffer, sizeof (buffer)); + + start_benchmark (&st); + + do + { + do + { + ret = gnutls_record_send (client, buffer, size); + } + while (ret == GNUTLS_E_AGAIN); + + if (ret < 0) + { + fprintf (stderr, "Failed sending to server\n"); + exit (1); + } + + do + { + ret = gnutls_record_recv (server, buffer, sizeof (buffer)); + } + while (ret == GNUTLS_E_AGAIN); + + if (ret < 0) + { + fprintf (stderr, "Failed receiving from client\n"); + exit (1); + } + + st.size += size; + } + while (benchmark_must_finish == 0); + + stop_benchmark (&st); + + gnutls_bye (client, GNUTLS_SHUT_WR); + gnutls_bye (server, GNUTLS_SHUT_WR); + + gnutls_deinit (client); + gnutls_deinit (server); + + gnutls_anon_free_client_credentials (c_anoncred); + gnutls_anon_free_server_credentials (s_anoncred); + + gnutls_dh_params_deinit (dh_params); + +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + { + gnutls_global_set_log_function (tls_log_func); + gnutls_global_set_log_level (2); + } + gnutls_global_init (); + + test_ciphersuite (PRIO_AES_CBC_SHA1, 1024); + test_ciphersuite (PRIO_AES_CBC_SHA1, 4096); + test_ciphersuite (PRIO_AES_CBC_SHA1, 8*1024); + test_ciphersuite (PRIO_AES_CBC_SHA1, 15*1024); + + test_ciphersuite (PRIO_CAMELLIA_CBC_SHA1, 1024); + test_ciphersuite (PRIO_CAMELLIA_CBC_SHA1, 4096); + test_ciphersuite (PRIO_CAMELLIA_CBC_SHA1, 8*1024); + test_ciphersuite (PRIO_CAMELLIA_CBC_SHA1, 15*1024); + + gnutls_global_deinit (); +} diff --git a/src/benchmark.c b/src/benchmark.c index 00d572a946..0af831cd1c 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -30,56 +30,10 @@ #include <time.h> #include <signal.h> #include "timespec.h" /* gnulib gettime */ +#include "benchmark.h" static unsigned char data[64 * 1024]; -static int must_finish = 0; - -#if !defined(_WIN32) -static void -alarm_handler (int signo) -{ - must_finish = 1; -} -#else -#include <windows.h> -DWORD WINAPI -alarm_handler (LPVOID lpParameter) -{ - HANDLE wtimer = *((HANDLE *) lpParameter); - WaitForSingleObject (wtimer, INFINITE); - must_finish = 1; - return 0; -} - -#define W32_ALARM_VARIABLES HANDLE wtimer = NULL, wthread = NULL; \ - LARGE_INTEGER alarm_timeout = { 0 , 0 } -#define W32_ALARM_TRIGGER(timeout, leave) { \ - wtimer = CreateWaitableTimer (NULL, TRUE, NULL); \ - if (wtimer == NULL) \ - { \ - fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ()); \ - leave; \ - } \ - wthread = CreateThread (NULL, 0, alarm_handler, &wtimer, 0, NULL); \ - if (wthread == NULL) \ - { \ - fprintf (stderr, "error: CreateThread %u\n", GetLastError ()); \ - leave; \ - } \ - alarm_timeout.QuadPart = timeout * 10000000; \ - if (SetWaitableTimer (wtimer, &alarm_timeout, 0, NULL, NULL, FALSE) == 0) \ - { \ - fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ()); \ - leave; \ - } \ - } -#define W32_ALARM_CLEANUP { \ - if (wtimer != NULL) \ - CloseHandle (wtimer); \ - if (wthread != NULL) \ - CloseHandle (wthread);} -#endif static void tls_log_func (int level, const char *str) @@ -88,40 +42,6 @@ tls_log_func (int level, const char *str) } static void -value2human (double bytes, double time, double *data, double *speed, - char *metric) -{ - if (bytes > 1000 && bytes < 1000 * 1000) - { - *data = ((double) bytes) / 1000; - *speed = *data / time; - strcpy (metric, "Kb"); - return; - } - else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) - { - *data = ((double) bytes) / (1000 * 1000); - *speed = *data / time; - strcpy (metric, "Mb"); - return; - } - else if (bytes >= 1000 * 1000 * 1000) - { - *data = ((double) bytes) / (1000 * 1000 * 1000); - *speed = *data / time; - strcpy (metric, "Gb"); - return; - } - else - { - *data = (double) bytes; - *speed = *data / time; - strcpy (metric, "bytes"); - return; - } -} - -static void cipher_mac_bench (int algo, int mac_algo, int size) { int ret; @@ -129,17 +49,10 @@ cipher_mac_bench (int algo, int mac_algo, int size) gnutls_hmac_hd_t mac_ctx; void *_key, *_iv; gnutls_datum_t key, iv; - struct timespec start, stop; - double secs; - double data_size = 0; - double dspeed, ddata; int blocksize = gnutls_cipher_get_block_size (algo); int keysize = gnutls_cipher_get_key_size (algo); - char metric[16]; int step = size*1024; -#if defined(_WIN32) - W32_ALARM_VARIABLES; -#endif + struct benchmark_st st; _key = malloc (keysize); if (_key == NULL) @@ -161,14 +74,7 @@ cipher_mac_bench (int algo, int mac_algo, int size) gnutls_mac_get_name(mac_algo), size); fflush (stdout); - must_finish = 0; -#if !defined(_WIN32) - alarm (5); -#else - W32_ALARM_TRIGGER(5, goto leave); -#endif - - gettime (&start); + start_benchmark(&st); ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size); if (ret < 0) @@ -190,22 +96,14 @@ cipher_mac_bench (int algo, int mac_algo, int size) { gnutls_hmac(mac_ctx, data, step); gnutls_cipher_encrypt (ctx, data, step); - data_size += step; + st.size += step; } - while (must_finish == 0); + while (benchmark_must_finish == 0); gnutls_cipher_deinit (ctx); gnutls_hmac_deinit(mac_ctx, NULL); - gettime (&stop); - - secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - - (start.tv_sec * 1000 + start.tv_nsec / (1000 * 1000))); - secs /= 1000; - - value2human (data_size, secs, &ddata, &dspeed, metric); - printf ("Encrypted and hashed %.2f %s in %.2f secs: ", ddata, metric, secs); - printf ("%.2f %s/sec\n", dspeed, metric); + stop_benchmark (&st); leave: free (_key); @@ -221,17 +119,10 @@ cipher_bench (int algo, int size, int aead) gnutls_cipher_hd_t ctx; void *_key, *_iv; gnutls_datum_t key, iv; - struct timespec start, stop; - double secs; - double data_size = 0; - double dspeed, ddata; int blocksize = gnutls_cipher_get_block_size (algo); int keysize = gnutls_cipher_get_key_size (algo); - char metric[16]; int step = size*1024; -#if defined(_WIN32) - W32_ALARM_VARIABLES; -#endif + struct benchmark_st st; _key = malloc (keysize); if (_key == NULL) @@ -254,10 +145,7 @@ cipher_bench (int algo, int size, int aead) size); fflush (stdout); - must_finish = 0; - alarm (5); - - gettime (&start); + start_benchmark(&st); ret = gnutls_cipher_init (&ctx, algo, &key, &iv); if (ret < 0) @@ -272,42 +160,27 @@ cipher_bench (int algo, int size, int aead) do { gnutls_cipher_encrypt (ctx, data, step); - data_size += step; + st.size += step; } - while (must_finish == 0); + while (benchmark_must_finish == 0); gnutls_cipher_deinit (ctx); - gettime (&stop); - - secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - - (start.tv_sec * 1000 + start.tv_nsec / (1000 * 1000))); - secs /= 1000; - - value2human (data_size, secs, &ddata, &dspeed, metric); - printf ("Encrypted %.2f %s in %.2f secs: ", ddata, metric, secs); - printf ("%.2f %s/sec\n", dspeed, metric); + stop_benchmark(&st); leave: free (_key); free (_iv); -#if defined(_WIN32) - W32_ALARM_CLEANUP; -#endif } static void mac_bench (int algo, int size) { void *_key; - struct timespec start, stop; - double secs; - double data_size = 0; - double ddata, dspeed; int blocksize = gnutls_hmac_get_len (algo); - char metric[16]; int step = size*1024; - + struct benchmark_st st; + _key = malloc (blocksize); if (_key == NULL) return; @@ -316,37 +189,17 @@ mac_bench (int algo, int size) printf ("Checking %s (%dkb payload)... ", gnutls_mac_get_name (algo), size); fflush (stdout); - must_finish = 0; -#if !defined(_WIN32) - alarm (5); -#else - W32_ALARM_TRIGGER(5, goto leave); -#endif - - gettime (&start); + start_benchmark(&st); do { gnutls_hmac_fast (algo, _key, blocksize, data, step, _key); - data_size += step; + st.size += step; } - while (must_finish == 0); + while (benchmark_must_finish == 0); - gettime (&stop); + stop_benchmark(&st); - secs = - (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - - (start.tv_sec * 1000 + start.tv_nsec / (1000 * 1000))); - secs /= 1000; - - value2human (data_size, secs, &ddata, &dspeed, metric); - - printf ("Hashed %.2f %s in %.2f secs: ", ddata, metric, secs); - printf ("%.2f %s/sec\n", dspeed, metric); -#if defined(_WIN32) -leave: - W32_ALARM_CLEANUP; -#endif free (_key); } @@ -358,10 +211,6 @@ main (int argc, char **argv) if (argc > 1) debug_level = 2; -#if !defined(_WIN32) - signal (SIGALRM, alarm_handler); -#endif - gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (debug_level); gnutls_global_init (); diff --git a/src/benchmark.h b/src/benchmark.h new file mode 100644 index 0000000000..0627e01b7b --- /dev/null +++ b/src/benchmark.h @@ -0,0 +1,22 @@ +#include <sys/time.h> +#include <time.h> +#include <signal.h> +#include "timespec.h" /* gnulib gettime */ + +typedef void (*sighandler_t)(int); + +struct benchmark_st +{ + struct timespec start; + unsigned long size; + sighandler_t old_handler; +#if defined(_WIN32) + W32_ALARM_VARIABLES; +#endif +}; + +extern int benchmark_must_finish; + +void start_benchmark(struct benchmark_st * st); +double stop_benchmark(struct benchmark_st * st); + diff --git a/tests/eagain-common.h b/tests/eagain-common.h index d75e78782f..dbc5f33a50 100644 --- a/tests/eagain-common.h +++ b/tests/eagain-common.h @@ -88,7 +88,6 @@ } \ while (transferred < 70000) - static char to_server[64*1024]; static size_t to_server_len = 0; @@ -229,3 +228,9 @@ int ret; return ret; } + +static void reset_buffers(void) +{ + to_server_len = 0; + to_client_len = 0; +} |