1
0
Fork 0

Adding upstream version 2.12.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-09 09:08:01 +01:00
parent 55035e358d
commit d1aefd7f7e
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
9 changed files with 233 additions and 28 deletions

36
CHANGES
View file

@ -1,3 +1,39 @@
2023-05-21 Jerry Lundström
Release 2.12.0
This release fixes a segfault when doing DNS-over-HTTPS and changes the
way maximum queries per second are handled.
The DNS-over-HTTPS module handled reconnecting incorrectly and destroyed
the nghttp2 context during callbacks. Thanks to the help from
@kgillis2000 it was quickly found and fixed.
The way maximum QPS is handled has been changed by Petr Špaček @pspacek
(ISC). The new way solves an over-shoot problem that happened due to
max QPS being counted for the whole runtime and based on completed
queries, not just sent.
A new option `qps_threshold_wait` has also been added. This controls
the threshold for using `nanosleep()` between sending packet and the
default is measured on start-up. If the time between packets, based on
max QPS `-Q`, is smaller then no sleep will be performed. This improves
performance when doing high max QPS limiting.
Other changes:
- `dnsperf`: Statistics output
- Fixed missing connection statistics if only reconnections happened
- Flush output to allow pipe/grep processing
- Add percentage on reconnections based on total connections
- Support OpenSSL 3.0+
9aca046 OpenSSL 3.0
6d3d6b4 Stats, DoH
316f901 qps_threshold_wait
ed52770 WIP: use busy wait only if necessary
32229b6 WIP: import nanosleep benchmark
1842b88 Fix dnsperf -Q to not overshot target value
2023-03-16 Jerry Lundström 2023-03-16 Jerry Lundström
Release 2.11.2 Release 2.11.2

20
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for dnsperf 2.11.2. # Generated by GNU Autoconf 2.69 for dnsperf 2.12.0.
# #
# Report bugs to <admin@dns-oarc.net>. # Report bugs to <admin@dns-oarc.net>.
# #
@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='dnsperf' PACKAGE_NAME='dnsperf'
PACKAGE_TARNAME='dnsperf' PACKAGE_TARNAME='dnsperf'
PACKAGE_VERSION='2.11.2' PACKAGE_VERSION='2.12.0'
PACKAGE_STRING='dnsperf 2.11.2' PACKAGE_STRING='dnsperf 2.12.0'
PACKAGE_BUGREPORT='admin@dns-oarc.net' PACKAGE_BUGREPORT='admin@dns-oarc.net'
PACKAGE_URL='https://github.com/DNS-OARC/dnsperf/issues' PACKAGE_URL='https://github.com/DNS-OARC/dnsperf/issues'
@ -1362,7 +1362,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures dnsperf 2.11.2 to adapt to many kinds of systems. \`configure' configures dnsperf 2.12.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1433,7 +1433,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of dnsperf 2.11.2:";; short | recursive ) echo "Configuration of dnsperf 2.12.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1572,7 +1572,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
dnsperf configure 2.11.2 dnsperf configure 2.12.0
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -1941,7 +1941,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by dnsperf $as_me 2.11.2, which was It was created by dnsperf $as_me 2.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2804,7 +2804,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='dnsperf' PACKAGE='dnsperf'
VERSION='2.11.2' VERSION='2.12.0'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -14436,7 +14436,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by dnsperf $as_me 2.11.2, which was This file was extended by dnsperf $as_me 2.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -14503,7 +14503,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
dnsperf config.status 2.11.2 dnsperf config.status 2.12.0
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View file

@ -16,7 +16,7 @@
# limitations under the License. # limitations under the License.
AC_PREREQ(2.64) AC_PREREQ(2.64)
AC_INIT([dnsperf], [2.11.2], [admin@dns-oarc.net], [dnsperf], [https://github.com/DNS-OARC/dnsperf/issues]) AC_INIT([dnsperf], [2.12.0], [admin@dns-oarc.net], [dnsperf], [https://github.com/DNS-OARC/dnsperf/issues])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([src/dnsperf.c]) AC_CONFIG_SRCDIR([src/dnsperf.c])
AC_CONFIG_HEADER([src/config.h]) AC_CONFIG_HEADER([src/config.h])

View file

@ -485,6 +485,8 @@ available in interval statistics.
Number of answers received within \fIstats_interval\fR can legitimately Number of answers received within \fIstats_interval\fR can legitimately
exceed number of queries sent, depending on answer latency, configured exceed number of queries sent, depending on answer latency, configured
\fItimeout\fR, and \fIstats_interval\fR. \fItimeout\fR, and \fIstats_interval\fR.
Only available in \fBdnsperf\fR.
.RE .RE
\fBlatency-histogram\fR \fBlatency-histogram\fR
@ -496,6 +498,29 @@ range for individual bins increases logarithmically.
This is done to to limit amount of memory required for histograms This is done to to limit amount of memory required for histograms
and also allows to visualize latency using logarithmic percentile histograms and also allows to visualize latency using logarithmic percentile histograms
with minimal postprocessing. with minimal postprocessing.
Only available in \fBdnsperf\fR and if compile time support was detected.
.RE
\fBqps-threshold-wait=<microseconds>\fR
.br
.RS
When using \fB-Q\fR to rate limit queries sent, this option control the
minimum time (in microseconds) there should be between queries to use
\fInanosleep()\fR to wait until sending the next query.
Setting to zero (0) will disable any call to \fInanosleep()\fR between
sending queries.
If the time between queries is lower then this, then no wait is performed
in order to have more precision on when to send the next query.
This is because during high QPS rate limiting it can take more time just
calling the functions to wait for when to send the next query then the
actually time between queries.
If not set, the average call-time to \fInanosleep()\fR will be measured
during startup.
Only available in \fBdnsperf\fR.
.RE .RE
.SH "SEE ALSO" .SH "SEE ALSO"
\fBresperf\fR(1) \fBresperf\fR(1)

View file

@ -102,6 +102,7 @@ typedef struct {
#ifdef USE_HISTOGRAMS #ifdef USE_HISTOGRAMS
bool latency_histogram; bool latency_histogram;
#endif #endif
int qps_threshold_wait;
} config_t; } config_t;
typedef struct { typedef struct {
@ -437,12 +438,16 @@ print_statistics(const config_t* config, const times_t* times, stats_t* stats, u
printf("\n"); printf("\n");
if (!stats->num_conn_completed) { if (!stats->num_conn_completed && !stats->num_conn_reconnect) {
fflush(stdout);
return; return;
} }
printf("Connection Statistics:\n\n"); printf("Connection Statistics:\n\n");
printf(" Reconnections: %" PRIu64 "\n\n", stats->num_conn_reconnect); printf(" Reconnections: %" PRIu64 " (%.2lf%% of %" PRIu64 " connections)\n\n",
stats->num_conn_reconnect,
PERF_SAFE_DIV(100.0 * stats->num_conn_reconnect, stats->num_conn_completed),
stats->num_conn_completed);
latency_avg = PERF_SAFE_DIV(stats->conn_latency_sum, stats->num_conn_completed); latency_avg = PERF_SAFE_DIV(stats->conn_latency_sum, stats->num_conn_completed);
printf(" Average Latency (s): %u.%06u", printf(" Average Latency (s): %u.%06u",
(unsigned int)(latency_avg / MILLION), (unsigned int)(latency_avg / MILLION),
@ -466,6 +471,7 @@ print_statistics(const config_t* config, const times_t* times, stats_t* stats, u
} }
printf("\n"); printf("\n");
fflush(stdout);
} }
/* /*
@ -532,6 +538,40 @@ stringify(unsigned int value)
return buf; return buf;
} }
static int
measure_nanosleep(config_t* config)
{
struct timespec start, stop, wait = { 0, 0 };
int err;
int i = 100;
if ((err = clock_gettime(CLOCK_REALTIME, &start))) {
return err;
}
for (; i; i--) {
if ((err = nanosleep(&wait, NULL))) {
return err;
}
}
if ((err = clock_gettime(CLOCK_REALTIME, &stop))) {
return err;
}
// Total time for 100 nanosleep() + 2 clock_gettime()
config->qps_threshold_wait = ((stop.tv_sec - start.tv_sec) * 1000000000 + stop.tv_nsec - start.tv_nsec)
// divided by 100 runs
/ 100
// add fudge
* 3
// converted to microseconds
/ 1000;
if (config->qps_threshold_wait < 0) {
config->qps_threshold_wait = 0;
}
return 0;
}
static void static void
setup(int argc, char** argv, config_t* config) setup(int argc, char** argv, config_t* config)
{ {
@ -559,6 +599,8 @@ setup(int argc, char** argv, config_t* config)
config->max_outstanding = DEFAULT_MAX_OUTSTANDING; config->max_outstanding = DEFAULT_MAX_OUTSTANDING;
config->mode = sock_udp; config->mode = sock_udp;
config->qps_threshold_wait = -1;
perf_opt_add('f', perf_opt_string, "family", perf_opt_add('f', perf_opt_string, "family",
"address family of DNS transport, inet or inet6", "any", "address family of DNS transport, inet or inet6", "any",
&family); &family);
@ -637,6 +679,8 @@ setup(int argc, char** argv, config_t* config)
perf_long_opt_add("latency-histogram", perf_opt_boolean, NULL, perf_long_opt_add("latency-histogram", perf_opt_boolean, NULL,
"collect and print detailed latency histograms", NULL, &config->latency_histogram); "collect and print detailed latency histograms", NULL, &config->latency_histogram);
#endif #endif
perf_long_opt_add("qps-threshold-wait", perf_opt_zpint, "microseconds",
"minimum threshold for enabling wait in rate limiting", stringify(config->qps_threshold_wait), &config->qps_threshold_wait);
bool log_stdout = false; bool log_stdout = false;
perf_opt_add('W', perf_opt_boolean, NULL, "log warnings and errors to stdout instead of stderr", NULL, &log_stdout); perf_opt_add('W', perf_opt_boolean, NULL, "log warnings and errors to stdout instead of stderr", NULL, &log_stdout);
@ -730,6 +774,14 @@ setup(int argc, char** argv, config_t* config)
perf_log_fatal("Unable to dynamic update, support not built in"); perf_log_fatal("Unable to dynamic update, support not built in");
} }
#endif #endif
if (config->qps_threshold_wait < 0) {
int err = measure_nanosleep(config);
if (err) {
char __s[256];
perf_log_fatal("Unable to measure nanosleep(): %s", perf_strerror_r(errno, __s, sizeof(__s)));
}
}
} }
static void static void
@ -803,7 +855,7 @@ do_send(void* arg)
stats_t* stats; stats_t* stats;
unsigned int max_packet_size; unsigned int max_packet_size;
perf_buffer_t msg; perf_buffer_t msg;
uint64_t now, run_time, req_time; uint64_t now, req_time, wait_us, q_sent = 0, q_step = 0, q_slice;
char input_data[MAX_INPUT_DATA]; char input_data[MAX_INPUT_DATA];
perf_buffer_t lines; perf_buffer_t lines;
perf_region_t used; perf_region_t used;
@ -824,8 +876,13 @@ do_send(void* arg)
perf_buffer_init(&msg, packet_buffer, max_packet_size); perf_buffer_init(&msg, packet_buffer, max_packet_size);
perf_buffer_init(&lines, input_data, sizeof(input_data)); perf_buffer_init(&lines, input_data, sizeof(input_data));
if (tinfo->max_qps > 0) {
q_step = MILLION / tinfo->max_qps;
}
wait_for_start(); wait_for_start();
now = perf_get_time(); now = perf_get_time();
req_time = now;
q_slice = now + MILLION;
while (!interrupted && now < times->stop_time) { while (!interrupted && now < times->stop_time) {
/* Avoid flooding the network too quickly. */ /* Avoid flooding the network too quickly. */
if (stats->num_sent < tinfo->max_outstanding && stats->num_sent % 2 == 1) { if (stats->num_sent < tinfo->max_outstanding && stats->num_sent % 2 == 1) {
@ -838,13 +895,49 @@ do_send(void* arg)
/* Rate limiting */ /* Rate limiting */
if (tinfo->max_qps > 0) { if (tinfo->max_qps > 0) {
run_time = now - times->start_time; /* the 1 second time slice where q_sent is calculated over */
req_time = (MILLION * stats->num_sent) / tinfo->max_qps; if (q_slice <= now) {
if (req_time > run_time) { q_slice += MILLION;
usleep(req_time - run_time); q_sent = 0;
req_time = now; // reset stepping, in case of clock sliding
}
/* limit QPS over the 1 second slice */
if (q_sent >= tinfo->max_qps) {
wait_us = q_slice - now;
if (config->qps_threshold_wait && wait_us > config->qps_threshold_wait) {
wait_us -= config->qps_threshold_wait;
struct timespec ts = { 0, 0 };
if (wait_us >= MILLION) {
ts.tv_sec = wait_us / MILLION;
ts.tv_nsec = (wait_us % MILLION) * 1000;
} else {
ts.tv_sec = 0;
ts.tv_nsec = wait_us * 1000;
}
nanosleep(&ts, NULL);
}
now = perf_get_time(); now = perf_get_time();
continue; continue;
} }
/* handle stepping to the next window to send a query on */
if (req_time > now) {
wait_us = req_time - now;
if (config->qps_threshold_wait && wait_us > config->qps_threshold_wait) {
wait_us -= config->qps_threshold_wait;
struct timespec ts = { 0, 0 };
if (wait_us >= MILLION) {
ts.tv_sec = wait_us / MILLION;
ts.tv_nsec = (wait_us % MILLION) * 1000;
} else {
ts.tv_sec = 0;
ts.tv_nsec = wait_us * 1000;
}
nanosleep(&ts, NULL);
}
now = perf_get_time();
continue;
}
req_time += q_step;
} }
PERF_LOCK(&tinfo->lock); PERF_LOCK(&tinfo->lock);
@ -980,6 +1073,7 @@ do_send(void* arg)
continue; continue;
} }
stats->num_sent++; stats->num_sent++;
q_sent++;
stats->total_request_size += length; stats->total_request_size += length;
} }

View file

@ -100,7 +100,7 @@ struct perf__doh_socket {
bool is_ready, is_conn_ready, is_ssl_ready, is_sending, is_post_sending; bool is_ready, is_conn_ready, is_ssl_ready, is_sending, is_post_sending;
// bool have_more; TODO // bool have_more; TODO
bool do_reconnect; bool do_reconnect, do_connect;
perf_sockaddr_t server, local; perf_sockaddr_t server, local;
size_t bufsize; size_t bufsize;
@ -254,7 +254,7 @@ static void perf__doh_reconnect(struct perf_net_socket* sock)
self->http2_code = 0; self->http2_code = 0;
self->http2_is_dns = false; self->http2_is_dns = false;
perf__doh_connect(sock); self->do_connect = true;
} }
// static ssize_t _recv_callback(nghttp2_session *session, uint8_t *buf, size_t length, int flags, void *sock) // static ssize_t _recv_callback(nghttp2_session *session, uint8_t *buf, size_t length, int flags, void *sock)
@ -623,6 +623,10 @@ static int perf__doh_sockready(struct perf_net_socket* sock, int pipe_fd, int64_
perf__doh_reconnect(sock); perf__doh_reconnect(sock);
self->do_reconnect = false; self->do_reconnect = false;
} }
if (self->do_connect) {
perf__doh_connect(sock);
self->do_connect = false;
}
if (self->is_ready) { if (self->is_ready) {
// do nghttp2 I/O send to flush outstanding frames // do nghttp2 I/O send to flush outstanding frames

View file

@ -175,6 +175,11 @@ static ssize_t perf__dot_recv(struct perf_net_socket* sock, void* buf, size_t le
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
errno = EAGAIN; errno = EAGAIN;
break; break;
#if OPENSSL_VERSION_NUMBER > 0x30000000L
case SSL_ERROR_SSL:
// OpenSSL 3.0+ returns this on EOF, treat everything as bad fd and reconnect
errno = EBADF;
#endif
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
switch (errno) { switch (errno) {
case EBADF: case EBADF:

View file

@ -183,15 +183,27 @@ perf_tsigkey_t* perf_tsig_parsekey(const char* arg)
perf_log_fatal("unable to setup TSIG, OpenSSL HMAC context failed to be created"); perf_log_fatal("unable to setup TSIG, OpenSSL HMAC context failed to be created");
} }
HMAC_CTX_init(tsigkey->hmac); HMAC_CTX_init(tsigkey->hmac);
#else #elif OPENSSL_VERSION_NUMBER < 0x30000000L
if (!(tsigkey->hmac = HMAC_CTX_new())) { if (!(tsigkey->hmac = HMAC_CTX_new())) {
perf_log_fatal("unable to setup TSIG, OpenSSL HMAC context failed to be created"); perf_log_fatal("unable to setup TSIG, OpenSSL HMAC context failed to be created");
} }
#else
if (!(tsigkey->pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, 0, key, keylen))) {
perf_log_fatal("unable to setup TSIG, OpenSSL EVP PKEY failed to be created");
}
if (!(tsigkey->mdctx = EVP_MD_CTX_create())) {
perf_log_fatal("unable to setup TSIG, OpenSSL EVP MD context failed to be created");
}
if (!EVP_DigestSignInit(tsigkey->mdctx, 0, md, 0, tsigkey->pkey)) {
perf_log_fatal("unable to setup TSIG, OpenSSL EVP DigestSign init failed");
}
#endif #endif
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (!HMAC_Init_ex(tsigkey->hmac, key, keylen, md, 0)) { if (!HMAC_Init_ex(tsigkey->hmac, key, keylen, md, 0)) {
perf_log_fatal("unable to setup TSIG, OpenSSL HMAC init failed"); perf_log_fatal("unable to setup TSIG, OpenSSL HMAC init failed");
} }
#endif
free(key); free(key);
@ -206,8 +218,11 @@ void perf_tsig_destroykey(perf_tsigkey_t** tsigkeyp)
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
HMAC_CTX_cleanup((*tsigkeyp)->hmac); HMAC_CTX_cleanup((*tsigkeyp)->hmac);
free((*tsigkeyp)->hmac); free((*tsigkeyp)->hmac);
#else #elif OPENSSL_VERSION_NUMBER < 0x30000000L
HMAC_CTX_free((*tsigkeyp)->hmac); HMAC_CTX_free((*tsigkeyp)->hmac);
#else
EVP_MD_CTX_free((*tsigkeyp)->mdctx);
EVP_PKEY_free((*tsigkeyp)->pkey);
#endif #endif
free(*tsigkeyp); free(*tsigkeyp);
@ -222,20 +237,27 @@ perf_result_t perf_add_tsig(perf_buffer_t* packet, perf_tsigkey_t* tsigkey)
unsigned char* base; unsigned char* base;
size_t rdlen, totallen; size_t rdlen, totallen;
unsigned char tmpdata[512], md[EVP_MAX_MD_SIZE]; unsigned char tmpdata[512], md[EVP_MAX_MD_SIZE];
unsigned int mdlen;
perf_buffer_t tmp; perf_buffer_t tmp;
uint32_t now; uint32_t now;
perf_result_t result; perf_result_t result;
now = time(NULL); now = time(NULL);
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (!HMAC_Init_ex(tsigkey->hmac, 0, 0, 0, 0)) { if (!HMAC_Init_ex(tsigkey->hmac, 0, 0, 0, 0)) {
perf_log_fatal("adding TSIG: OpenSSL HMAC reinit failed"); perf_log_fatal("adding TSIG: OpenSSL HMAC reinit failed");
} }
if (!HMAC_Update(tsigkey->hmac, perf_buffer_base(packet), perf_buffer_usedlength(packet))) { if (!HMAC_Update(tsigkey->hmac, perf_buffer_base(packet), perf_buffer_usedlength(packet))) {
perf_log_fatal("adding TSIG: OpenSSL HMAC update failed"); perf_log_fatal("adding TSIG: OpenSSL HMAC update failed");
} }
#else
if (!EVP_DigestSignInit(tsigkey->mdctx, 0, 0, 0, 0)) {
perf_log_fatal("adding TSIG: OpenSSL EVP DigestSign reinit failed");
}
if (!EVP_DigestSignUpdate(tsigkey->mdctx, perf_buffer_base(packet), perf_buffer_usedlength(packet))) {
perf_log_fatal("adding TSIG: OpenSSL EVP DigestSign update failed");
}
#endif
/* Digest the TSIG record */ /* Digest the TSIG record */
perf_buffer_init(&tmp, tmpdata, sizeof tmpdata); perf_buffer_init(&tmp, tmpdata, sizeof tmpdata);
@ -267,14 +289,23 @@ perf_result_t perf_add_tsig(perf_buffer_t* packet, perf_tsigkey_t* tsigkey)
perf_buffer_putuint16(&tmp, 0); /* error */ perf_buffer_putuint16(&tmp, 0); /* error */
perf_buffer_putuint16(&tmp, 0); /* other length */ perf_buffer_putuint16(&tmp, 0); /* other length */
#if OPENSSL_VERSION_NUMBER < 0x30000000L
unsigned int mdlen = sizeof(md);
if (!HMAC_Update(tsigkey->hmac, perf_buffer_base(&tmp), perf_buffer_usedlength(&tmp))) { if (!HMAC_Update(tsigkey->hmac, perf_buffer_base(&tmp), perf_buffer_usedlength(&tmp))) {
perf_log_fatal("adding TSIG: OpenSSL HMAC update failed"); perf_log_fatal("adding TSIG: OpenSSL HMAC update failed");
} }
mdlen = sizeof(md);
if (!HMAC_Final(tsigkey->hmac, md, &mdlen)) { if (!HMAC_Final(tsigkey->hmac, md, &mdlen)) {
perf_log_fatal("adding TSIG: OpenSSL HMAC final failed"); perf_log_fatal("adding TSIG: OpenSSL HMAC final failed");
} }
#else
size_t mdlen = sizeof(md);
if (!EVP_DigestSignUpdate(tsigkey->mdctx, perf_buffer_base(&tmp), perf_buffer_usedlength(&tmp))) {
perf_log_fatal("adding TSIG: OpenSSL EVP DigestSign update failed");
}
if (!EVP_DigestSignFinal(tsigkey->mdctx, md, &mdlen)) {
perf_log_fatal("adding TSIG: OpenSSL EVP DigestSign final failed");
}
#endif
/* Make sure everything will fit */ /* Make sure everything will fit */
rdlen = tsigkey->alglen + 18 + mdlen; rdlen = tsigkey->alglen + 18 + mdlen;

View file

@ -23,13 +23,23 @@
#ifndef PERF_TSIG_H #ifndef PERF_TSIG_H
#define PERF_TSIG_H 1 #define PERF_TSIG_H 1
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER < 0x30000000L
#include <openssl/hmac.h> #include <openssl/hmac.h>
#else
#include <openssl/evp.h>
#endif
typedef struct perf_tsigkey { typedef struct perf_tsigkey {
char name[256]; char name[256];
size_t namelen, alglen; size_t namelen, alglen;
const char* alg; const char* alg;
HMAC_CTX* hmac; #if OPENSSL_VERSION_NUMBER < 0x30000000L
HMAC_CTX* hmac;
#else
EVP_PKEY* pkey;
EVP_MD_CTX* mdctx;
#endif
} perf_tsigkey_t; } perf_tsigkey_t;
perf_tsigkey_t* perf_tsig_parsekey(const char* arg); perf_tsigkey_t* perf_tsig_parsekey(const char* arg);