#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
-#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/ocsp.h>
#ifndef OPENSSL_NO_DH
static int async = 0;
static int use_sendfile = 0;
+static int use_zc_sendfile = 0;
static const char *session_id_prefix = NULL;
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, OPT_KTLS,
- OPT_TFO,
+ OPT_USE_ZC_SENDFILE,
+ OPT_TFO, OPT_CERT_COMP,
OPT_R_ENUM,
OPT_S_ENUM,
OPT_V_ENUM,
"No verify output except verify errors"},
{"ign_eof", OPT_IGN_EOF, '-', "Ignore input EOF (default when -quiet)"},
{"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input EOF"},
+#ifndef OPENSSL_NO_COMP_ALG
+ {"cert_comp", OPT_CERT_COMP, '-', "Pre-compress server certificates"},
+#endif
#ifndef OPENSSL_NO_OCSP
OPT_SECTION("OCSP"),
#ifndef OPENSSL_NO_KTLS
{"ktls", OPT_KTLS, '-', "Enable Kernel TLS for sending and receiving"},
{"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"},
+ {"zerocopy_sendfile", OPT_USE_ZC_SENDFILE, '-', "Use zerocopy mode of KTLS sendfile"},
#endif
OPT_R_OPTIONS,
int enable_ktls = 0;
#endif
int tfo = 0;
+ int cert_comp = 0;
/* Init of few remaining global variables */
local_argc = argc;
s_brief = 0;
async = 0;
use_sendfile = 0;
+ use_zc_sendfile = 0;
port = OPENSSL_strdup(PORT);
cctx = SSL_CONF_CTX_new();
case OPT_UNIX:
socket_family = AF_UNIX;
OPENSSL_free(host); host = OPENSSL_strdup(opt_arg());
+ if (host == NULL)
+ goto end;
OPENSSL_free(port); port = NULL;
break;
case OPT_UNLINK:
case OPT_SENDFILE:
#ifndef OPENSSL_NO_KTLS
use_sendfile = 1;
+#endif
+ break;
+ case OPT_USE_ZC_SENDFILE:
+#ifndef OPENSSL_NO_KTLS
+ use_zc_sendfile = 1;
#endif
break;
case OPT_IGNORE_UNEXPECTED_EOF:
case OPT_TFO:
tfo = 1;
break;
+ case OPT_CERT_COMP:
+ cert_comp = 1;
+ break;
}
}
#endif
#ifndef OPENSSL_NO_KTLS
+ if (use_zc_sendfile && !use_sendfile) {
+ BIO_printf(bio_out, "Warning: -zerocopy_sendfile depends on -sendfile, enabling -sendfile now.\n");
+ use_sendfile = 1;
+ }
+
if (use_sendfile && enable_ktls == 0) {
BIO_printf(bio_out, "Warning: -sendfile depends on -ktls, enabling -ktls now.\n");
enable_ktls = 1;
#ifndef OPENSSL_NO_KTLS
if (enable_ktls)
SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS);
+ if (use_zc_sendfile)
+ SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE);
#endif
if (max_send_fragment > 0
if (recv_max_early_data >= 0)
SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data);
+ if (cert_comp) {
+ BIO_printf(bio_s_out, "Compressing certificates\n");
+ if (!SSL_CTX_compress_certs(ctx, 0))
+ BIO_printf(bio_s_out, "Error compressing certs on ctx\n");
+ if (ctx2 != NULL && !SSL_CTX_compress_certs(ctx2, 0))
+ BIO_printf(bio_s_out, "Error compressing certs on ctx2\n");
+ }
+
if (rev)
server_cb = rev_body;
else if (www)
SSL_CTX_sess_get_cache_size(ssl_ctx));
}
+static long int count_reads_callback(BIO *bio, int cmd, const char *argp, size_t len,
+ int argi, long argl, int ret, size_t *processed)
+{
+ unsigned int *p_counter = (unsigned int *)BIO_get_callback_arg(bio);
+
+ switch (cmd) {
+ case BIO_CB_READ: /* No break here */
+ case BIO_CB_GETS:
+ if (p_counter != NULL)
+ ++*p_counter;
+ break;
+ default:
+ break;
+ }
+
+ if (s_debug) {
+ BIO_set_callback_arg(bio, (char *)bio_s_out);
+ ret = (int)bio_dump_callback(bio, cmd, argp, len, argi, argl, ret, processed);
+ BIO_set_callback_arg(bio, (char *)p_counter);
+ }
+
+ return ret;
+}
+
static int sv_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
SSL_set_accept_state(con);
/* SSL_set_fd(con,s); */
- if (s_debug) {
- BIO_set_callback_ex(SSL_get_rbio(con), bio_dump_callback);
- BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
- }
+ BIO_set_callback_ex(SSL_get_rbio(con), count_reads_callback);
if (s_msg) {
#ifndef OPENSSL_NO_SSL_TRACE
if (s_msg == 2)
*/
if ((!async || !SSL_waiting_for_async(con))
&& !SSL_is_init_finished(con)) {
+ /*
+ * Count number of reads during init_ssl_connection.
+ * It helps us to distinguish configuration errors from errors
+ * caused by a client.
+ */
+ unsigned int read_counter = 0;
+
+ BIO_set_callback_arg(SSL_get_rbio(con), (char *)&read_counter);
i = init_ssl_connection(con);
+ BIO_set_callback_arg(SSL_get_rbio(con), NULL);
+ /*
+ * If initialization fails without reads, then
+ * there was a fatal error in configuration.
+ */
+ if (i <= 0 && read_counter == 0) {
+ ret = -1;
+ goto err;
+ }
if (i < 0) {
ret = 0;
goto err;
}
/* lets make the output buffer a reasonable size */
- if (!BIO_set_write_buffer_size(io, bufsize))
+ if (BIO_set_write_buffer_size(io, bufsize) <= 0)
goto err;
if ((con = SSL_new(ctx)) == NULL)
continue;
}
#endif
- ossl_sleep(1000);
+ OSSL_sleep(1000);
continue;
}
} else if (i == 0) { /* end of input */
goto err;
/* lets make the output buffer a reasonable size */
- if (!BIO_set_write_buffer_size(io, bufsize))
+ if (BIO_set_write_buffer_size(io, bufsize) <= 0)
goto err;
if ((con = SSL_new(ctx)) == NULL)
continue;
}
#endif
- ossl_sleep(1000);
+ OSSL_sleep(1000);
continue;
}
} else if (i == 0) { /* end of input */