Skip to content

Commit

Permalink
Add TLS Server Name Indication extension support
Browse files Browse the repository at this point in the history
Support for the TLS SNI extension when querying with DNS-over-HTTPS or
DNS-over-TLS.

Otherwise some TLS servers respond with 'Handshake Failure' instead
of the server hello. When passing the '-v' flag to resperf, it logs:
    Warning: failed to send packet: socket 0 not ready

This is solved with a new command line argument:
    -O tls-sni=example.org
  • Loading branch information
Tjeu Kayim committed May 29, 2023
1 parent be7d2a4 commit 5fb2282
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/dnsperf.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,13 @@ The HTTP method to use when querying with DNS-over-HTTPS, default is GET.
Available methods are: GET, POST.
.RE

\fBtls-sni=\fISERVER_NAME\fR
.br
.RS
The TLS Server Name Indication (SNI) to use when querying with DNS-over-HTTPS or DNS-over-TLS,
defaults to leaving out the SNI extension in the client hello.
.RE

\fBsuppress=\fIMESSAGE[,MESSAGE,...]\fR
.br
.RS
Expand Down
2 changes: 2 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ struct perf_net_socket* perf_net_doh_opensocket(const perf_sockaddr_t*, const pe

void perf_net_doh_parse_uri(const char*);
void perf_net_doh_parse_method(const char*);
void perf_net_doh_set_sni(const char*);
void perf_net_dot_set_sni(const char*);
void perf_net_doh_set_max_concurrent_streams(size_t);

void perf_net_stats_init(enum perf_net_mode);
Expand Down
10 changes: 10 additions & 0 deletions src/net_doh.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
#include <stdbool.h>
#include <unistd.h>
#include <openssl/err.h>
#include <sys/socket.h>
Expand All @@ -57,6 +58,7 @@ enum perf_doh_method {
doh_method_post
};
static enum perf_doh_method doh_method = doh_method_get;
static const char* doh_sni = NULL;
static size_t doh_max_concurr = 100;

#define self ((struct perf__doh_socket*)sock)
Expand Down Expand Up @@ -152,6 +154,11 @@ void perf_net_doh_parse_method(const char* method)
exit(1);
}

void perf_net_doh_set_sni(const char* sni)
{
doh_sni = sni;
}

void perf_net_doh_set_max_concurrent_streams(size_t max_concurr)
{
doh_max_concurr = max_concurr;
Expand Down Expand Up @@ -187,6 +194,9 @@ static void perf__doh_connect(struct perf_net_socket* sock)
if (!(ret = SSL_set_fd(self->ssl, sock->fd))) {
perf_log_fatal("SSL_set_fd(): %s", ERR_error_string(SSL_get_error(self->ssl, ret), 0));
}
if (doh_sni && !(ret = SSL_set_tlsext_host_name(self->ssl, doh_sni))) {
perf_log_fatal("SSL_set_tlsext_host_name(): %s", ERR_error_string(SSL_get_error(self->ssl, ret), 0));
}

if (self->server.sa.sa.sa_family == AF_INET6) {
int on = 1;
Expand Down
10 changes: 10 additions & 0 deletions src/net_dot.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <unistd.h>
#include <openssl/err.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ck_pr.h>

static SSL_CTX* ssl_ctx = 0;
static const char* dot_sni = NULL;

#define self ((struct perf__dot_socket*)sock)

Expand All @@ -61,6 +63,11 @@ struct perf__dot_socket {
uint64_t nqpc_ts;
};

void perf_net_dot_set_sni(const char* sni)
{
dot_sni = sni;
}

static void perf__dot_connect(struct perf_net_socket* sock)
{
int ret;
Expand All @@ -85,6 +92,9 @@ static void perf__dot_connect(struct perf_net_socket* sock)
if (!(ret = SSL_set_fd(self->ssl, sock->fd))) {
perf_log_fatal("SSL_set_fd(): %s", ERR_error_string(SSL_get_error(self->ssl, ret), 0));
}
if (dot_sni && !(ret = SSL_set_tlsext_host_name(self->ssl, dot_sni))) {
perf_log_fatal("SSL_set_tlsext_host_name(): %s", ERR_error_string(SSL_get_error(self->ssl, ret), 0));
}

if (self->server.sa.sa.sa_family == AF_INET6) {
int on = 1;
Expand Down
7 changes: 7 additions & 0 deletions src/resperf.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ static void setup(int argc, char** argv)
const char* edns_option_str = NULL;
const char* doh_uri = DEFAULT_DOH_URI;
const char* doh_method = DEFAULT_DOH_METHOD;
const char* tls_sni = NULL;
const char* local_suppress = 0;

size_t num_queries_per_conn = 0;
Expand Down Expand Up @@ -337,6 +338,8 @@ static void setup(int argc, char** argv)
"the URI to use for DNS-over-HTTPS", DEFAULT_DOH_URI, &doh_uri);
perf_long_opt_add("doh-method", perf_opt_string, "doh_method",
"the HTTP method to use for DNS-over-HTTPS: GET or POST", DEFAULT_DOH_METHOD, &doh_method);
perf_long_opt_add("tls-sni", perf_opt_string, "tls_sni",
"set the TLS Server Name Indication extension in the client hello for DoH and DoT", NULL, &tls_sni);
perf_long_opt_add("suppress", perf_opt_string, "message[,message,...]",
"suppress messages/warnings, see dnsperf(1) man-page for list of message types", NULL, &local_suppress);
perf_long_opt_add("num-queries-per-conn", perf_opt_uint, "queries",
Expand Down Expand Up @@ -373,6 +376,10 @@ static void setup(int argc, char** argv)
if (doh_method) {
perf_net_doh_parse_method(doh_method);
}
if (tls_sni && strlen(tls_sni)) {
perf_net_doh_set_sni(tls_sni);
perf_net_dot_set_sni(tls_sni);
}
perf_net_doh_set_max_concurrent_streams(max_outstanding);

if (max_outstanding > nsocks * DEFAULT_MAX_OUTSTANDING)
Expand Down

0 comments on commit 5fb2282

Please sign in to comment.