commit
2f6e1ac336
|
@ -2122,6 +2122,13 @@ int HttpServer::run() {
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
|
||||||
|
if (nghttp2::ssl::ssl_ctx_set_proto_versions(
|
||||||
|
ssl_ctx, nghttp2::ssl::NGHTTP2_TLS_MIN_VERSION,
|
||||||
|
nghttp2::ssl::NGHTTP2_TLS_MAX_VERSION) != 0) {
|
||||||
|
std::cerr << "Could not set TLS versions" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
|
if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
|
||||||
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
|
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -2242,6 +2242,13 @@ int main(int argc, char **argv) {
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
|
||||||
|
if (nghttp2::ssl::ssl_ctx_set_proto_versions(
|
||||||
|
ssl_ctx, nghttp2::ssl::NGHTTP2_TLS_MIN_VERSION,
|
||||||
|
nghttp2::ssl::NGHTTP2_TLS_MAX_VERSION) != 0) {
|
||||||
|
std::cerr << "Could not set TLS versions" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (SSL_CTX_set_cipher_list(ssl_ctx, config.ciphers.c_str()) == 0) {
|
if (SSL_CTX_set_cipher_list(ssl_ctx, config.ciphers.c_str()) == 0) {
|
||||||
std::cerr << "SSL_CTX_set_cipher_list with " << config.ciphers
|
std::cerr << "SSL_CTX_set_cipher_list with " << config.ciphers
|
||||||
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr)
|
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr)
|
||||||
|
|
|
@ -2246,6 +2246,15 @@ int communicate(
|
||||||
SSL_CTX_set_options(ssl_ctx, ssl_opts);
|
SSL_CTX_set_options(ssl_ctx, ssl_opts);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
|
||||||
|
if (nghttp2::ssl::ssl_ctx_set_proto_versions(
|
||||||
|
ssl_ctx, nghttp2::ssl::NGHTTP2_TLS_MIN_VERSION,
|
||||||
|
nghttp2::ssl::NGHTTP2_TLS_MAX_VERSION) != 0) {
|
||||||
|
std::cerr << "[ERROR] Could not set TLS versions" << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
|
||||||
if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
|
if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
|
||||||
std::cerr << "[ERROR] " << ERR_error_string(ERR_get_error(), nullptr)
|
std::cerr << "[ERROR] " << ERR_error_string(ERR_get_error(), nullptr)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
48
src/shrpx.cc
48
src/shrpx.cc
|
@ -1369,7 +1369,11 @@ constexpr auto DEFAULT_NPN_LIST = StringRef::from_lit("h2,h2-16,h2-14,"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr auto DEFAULT_TLS_MIN_PROTO_VERSION = StringRef::from_lit("TLSv1.1");
|
constexpr auto DEFAULT_TLS_MIN_PROTO_VERSION = StringRef::from_lit("TLSv1.1");
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
constexpr auto DEFAULT_TLS_MAX_PROTO_VERSION = StringRef::from_lit("TLSv1.3");
|
||||||
|
#else // !TLS1_3_VERSION
|
||||||
constexpr auto DEFAULT_TLS_MAX_PROTO_VERSION = StringRef::from_lit("TLSv1.2");
|
constexpr auto DEFAULT_TLS_MAX_PROTO_VERSION = StringRef::from_lit("TLSv1.2");
|
||||||
|
#endif // !TLS1_3_VERSION
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1427,8 +1431,10 @@ void fill_default_config(Config *config) {
|
||||||
tlsconf.ciphers = StringRef::from_lit(nghttp2::ssl::DEFAULT_CIPHER_LIST);
|
tlsconf.ciphers = StringRef::from_lit(nghttp2::ssl::DEFAULT_CIPHER_LIST);
|
||||||
tlsconf.client.ciphers =
|
tlsconf.client.ciphers =
|
||||||
StringRef::from_lit(nghttp2::ssl::DEFAULT_CIPHER_LIST);
|
StringRef::from_lit(nghttp2::ssl::DEFAULT_CIPHER_LIST);
|
||||||
tlsconf.min_proto_version = TLS1_1_VERSION;
|
tlsconf.min_proto_version =
|
||||||
tlsconf.max_proto_version = TLS1_2_VERSION;
|
ssl::proto_version_from_string(DEFAULT_TLS_MIN_PROTO_VERSION);
|
||||||
|
tlsconf.max_proto_version =
|
||||||
|
ssl::proto_version_from_string(DEFAULT_TLS_MAX_PROTO_VERSION);
|
||||||
#if OPENSSL_1_1_API
|
#if OPENSSL_1_1_API
|
||||||
tlsconf.ecdh_curves = StringRef::from_lit("X25519:P-256:P-384:P-521");
|
tlsconf.ecdh_curves = StringRef::from_lit("X25519:P-256:P-384:P-521");
|
||||||
#else // !OPENSSL_1_1_API
|
#else // !OPENSSL_1_1_API
|
||||||
|
@ -2058,23 +2064,33 @@ SSL/TLS:
|
||||||
Path to file that contains client certificate used in
|
Path to file that contains client certificate used in
|
||||||
backend client authentication.
|
backend client authentication.
|
||||||
--tls-min-proto-version=<VER>
|
--tls-min-proto-version=<VER>
|
||||||
Specify minimum SSL/TLS protocol. The following
|
Specify minimum SSL/TLS protocol. The name matching is
|
||||||
protocols are available: TLSv1.2, TLSv1.1 and TLSv1.0.
|
done in case-insensitive manner. The versions between
|
||||||
The name matching is done in case-insensitive manner.
|
--tls-min-proto-version and --tls-max-proto-version are
|
||||||
The versions between --tls-min-proto-version and
|
enabled. If the protocol list advertised by client does
|
||||||
--tls-max-proto-version are enabled. If the protocol
|
not overlap this range, you will receive the error
|
||||||
list advertised by client does not overlap this range,
|
message "unknown protocol". The available versions are:
|
||||||
you will receive the error message "unknown protocol".
|
)"
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
"TLSv1.3, "
|
||||||
|
#endif // TLS1_3_VERSION
|
||||||
|
"TLSv1.2, TLSv1.1, and TLSv1.0"
|
||||||
|
R"(
|
||||||
Default: )"
|
Default: )"
|
||||||
<< DEFAULT_TLS_MIN_PROTO_VERSION << R"(
|
<< DEFAULT_TLS_MIN_PROTO_VERSION << R"(
|
||||||
--tls-max-proto-version=<VER>
|
--tls-max-proto-version=<VER>
|
||||||
Specify maximum SSL/TLS protocol. The following
|
Specify maximum SSL/TLS protocol. The name matching is
|
||||||
protocols are available: TLSv1.2, TLSv1.1 and TLSv1.0.
|
done in case-insensitive manner. The versions between
|
||||||
The name matching is done in case-insensitive manner.
|
--tls-min-proto-version and --tls-max-proto-version are
|
||||||
The versions between --tls-min-proto-version and
|
enabled. If the protocol list advertised by client does
|
||||||
--tls-max-proto-version are enabled. If the protocol
|
not overlap this range, you will receive the error
|
||||||
list advertised by client does not overlap this range,
|
message "unknown protocol". The available versions are:
|
||||||
you will receive the error message "unknown protocol".
|
)"
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
"TLSv1.3, "
|
||||||
|
#endif // TLS1_3_VERSION
|
||||||
|
"TLSv1.2, TLSv1.1, and TLSv1.0"
|
||||||
|
R"(
|
||||||
Default: )"
|
Default: )"
|
||||||
<< DEFAULT_TLS_MAX_PROTO_VERSION << R"(
|
<< DEFAULT_TLS_MAX_PROTO_VERSION << R"(
|
||||||
--tls-ticket-key-file=<PATH>
|
--tls-ticket-key-file=<PATH>
|
||||||
|
|
|
@ -639,55 +639,6 @@ long int create_tls_proto_mask(const std::vector<StringRef> &tls_proto_list) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OPENSSL_IS_BORINGSSL)
|
|
||||||
namespace {
|
|
||||||
int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max) {
|
|
||||||
SSL_CTX_set_min_version(ssl_ctx, min);
|
|
||||||
SSL_CTX_set_max_version(ssl_ctx, max);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
#elif OPENSSL_1_1_API
|
|
||||||
namespace {
|
|
||||||
int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max) {
|
|
||||||
if (SSL_CTX_set_min_proto_version(ssl_ctx, min) != 1 ||
|
|
||||||
SSL_CTX_set_max_proto_version(ssl_ctx, max) != 1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
#else // !OPENSSL_1_1_API
|
|
||||||
namespace {
|
|
||||||
int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max) {
|
|
||||||
long int opts = 0;
|
|
||||||
|
|
||||||
// TODO We depends on the ordering of protocol version macro in
|
|
||||||
// OpenSSL.
|
|
||||||
if (min > TLS1_VERSION) {
|
|
||||||
opts |= SSL_OP_NO_TLSv1;
|
|
||||||
}
|
|
||||||
if (min > TLS1_1_VERSION) {
|
|
||||||
opts |= SSL_OP_NO_TLSv1_1;
|
|
||||||
}
|
|
||||||
if (min > TLS1_2_VERSION) {
|
|
||||||
opts |= SSL_OP_NO_TLSv1_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max < TLS1_2_VERSION) {
|
|
||||||
opts |= SSL_OP_NO_TLSv1_2;
|
|
||||||
}
|
|
||||||
if (max < TLS1_1_VERSION) {
|
|
||||||
opts |= SSL_OP_NO_TLSv1_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSL_CTX_set_options(ssl_ctx, opts);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
#endif // !OPENSSL_1_1_API
|
|
||||||
|
|
||||||
SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||||
const std::vector<uint8_t> &sct_data
|
const std::vector<uint8_t> &sct_data
|
||||||
#ifdef HAVE_NEVERBLEED
|
#ifdef HAVE_NEVERBLEED
|
||||||
|
@ -712,10 +663,9 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||||
|
|
||||||
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
|
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
|
||||||
|
|
||||||
if (ssl_ctx_set_proto_versions(ssl_ctx, tlsconf.min_proto_version,
|
if (nghttp2::ssl::ssl_ctx_set_proto_versions(
|
||||||
tlsconf.max_proto_version) != 0) {
|
ssl_ctx, tlsconf.min_proto_version, tlsconf.max_proto_version) != 0) {
|
||||||
LOG(FATAL) << "Could not set TLS protocol version: "
|
LOG(FATAL) << "Could not set TLS protocol version";
|
||||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
|
||||||
DIE();
|
DIE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,10 +903,9 @@ SSL_CTX *create_ssl_client_context(
|
||||||
|
|
||||||
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
|
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
|
||||||
|
|
||||||
if (ssl_ctx_set_proto_versions(ssl_ctx, tlsconf.min_proto_version,
|
if (nghttp2::ssl::ssl_ctx_set_proto_versions(
|
||||||
tlsconf.max_proto_version) != 0) {
|
ssl_ctx, tlsconf.min_proto_version, tlsconf.max_proto_version) != 0) {
|
||||||
LOG(FATAL) << "Could not set TLS protocol version: "
|
LOG(FATAL) << "Could not set TLS protocol version";
|
||||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
|
||||||
DIE();
|
DIE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1742,6 +1691,11 @@ SSL_SESSION *reuse_tls_session(const TLSSessionCache &cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int proto_version_from_string(const StringRef &v) {
|
int proto_version_from_string(const StringRef &v) {
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
if (util::strieq_l("TLSv1.3", v)) {
|
||||||
|
return TLS1_3_VERSION;
|
||||||
|
}
|
||||||
|
#endif // TLS1_3_VERSION
|
||||||
if (util::strieq_l("TLSv1.2", v)) {
|
if (util::strieq_l("TLSv1.2", v)) {
|
||||||
return TLS1_2_VERSION;
|
return TLS1_2_VERSION;
|
||||||
}
|
}
|
||||||
|
|
43
src/ssl.cc
43
src/ssl.cc
|
@ -83,6 +83,10 @@ const char *get_tls_protocol(SSL *ssl) {
|
||||||
return "SSLv2";
|
return "SSLv2";
|
||||||
case SSL3_VERSION:
|
case SSL3_VERSION:
|
||||||
return "SSLv3";
|
return "SSLv3";
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
case TLS1_3_VERSION:
|
||||||
|
return "TLSv1.3";
|
||||||
|
#endif // TLS1_3_VERSION
|
||||||
case TLS1_2_VERSION:
|
case TLS1_2_VERSION:
|
||||||
return "TLSv1.2";
|
return "TLSv1.2";
|
||||||
case TLS1_1_VERSION:
|
case TLS1_1_VERSION:
|
||||||
|
@ -159,6 +163,45 @@ void libssl_init() {
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max) {
|
||||||
|
#if OPENSSL_1_1_API
|
||||||
|
if (SSL_CTX_set_min_proto_version(ssl_ctx, min) != 1 ||
|
||||||
|
SSL_CTX_set_max_proto_version(ssl_ctx, max) != 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#elif defined(OPENSSL_IS_BORINGSSL)
|
||||||
|
SSL_CTX_set_min_version(ssl_ctx, min);
|
||||||
|
SSL_CTX_set_max_version(ssl_ctx, max);
|
||||||
|
return 0;
|
||||||
|
#else // !defined(OPENSSL_IS_BORINGSSL)
|
||||||
|
long int opts = 0;
|
||||||
|
|
||||||
|
// TODO We depends on the ordering of protocol version macro in
|
||||||
|
// OpenSSL.
|
||||||
|
if (min > TLS1_VERSION) {
|
||||||
|
opts |= SSL_OP_NO_TLSv1;
|
||||||
|
}
|
||||||
|
if (min > TLS1_1_VERSION) {
|
||||||
|
opts |= SSL_OP_NO_TLSv1_1;
|
||||||
|
}
|
||||||
|
if (min > TLS1_2_VERSION) {
|
||||||
|
opts |= SSL_OP_NO_TLSv1_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max < TLS1_2_VERSION) {
|
||||||
|
opts |= SSL_OP_NO_TLSv1_2;
|
||||||
|
}
|
||||||
|
if (max < TLS1_1_VERSION) {
|
||||||
|
opts |= SSL_OP_NO_TLSv1_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_CTX_set_options(ssl_ctx, opts);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif // !defined(OPENSSL_IS_BORINGSSL)
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ssl
|
} // namespace ssl
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
29
src/ssl.h
29
src/ssl.h
|
@ -49,7 +49,25 @@ public:
|
||||||
// suites by mozilla.
|
// suites by mozilla.
|
||||||
//
|
//
|
||||||
// https://wiki.mozilla.org/Security/Server_Side_TLS
|
// https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||||
|
//
|
||||||
|
// Plus TLSv1.3 cipher suites if defined.
|
||||||
constexpr char DEFAULT_CIPHER_LIST[] =
|
constexpr char DEFAULT_CIPHER_LIST[] =
|
||||||
|
#ifdef TLS1_3_TXT_AES_256_GCM_SHA384
|
||||||
|
TLS1_3_TXT_AES_256_GCM_SHA384
|
||||||
|
":"
|
||||||
|
#endif // TLS1_3_TXT_AES_256_GCM_SHA384
|
||||||
|
#ifdef TLS1_3_TXT_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS1_3_TXT_CHACHA20_POLY1305_SHA256 ":"
|
||||||
|
#endif // TLS1_3_TXT_CHACHA20_POLY1305_SHA256
|
||||||
|
#ifdef TLS1_3_TXT_AES_128_GCM_SHA256
|
||||||
|
TLS1_3_TXT_AES_128_GCM_SHA256 ":"
|
||||||
|
#endif // TLS1_3_TXT_AES_128_GCM_SHA256
|
||||||
|
#ifdef TLS1_3_TXT_AES_128_CCM_SHA256
|
||||||
|
TLS1_3_TXT_AES_128_CCM_SHA256 ":"
|
||||||
|
#endif // TLS1_3_TXT_AES_128_CCM_SHA256
|
||||||
|
#ifdef TLS1_3_TXT_AES_128_CCM_8_SHA256
|
||||||
|
TLS1_3_TXT_AES_128_CCM_8_SHA256 ":"
|
||||||
|
#endif // TLS1_3_TXT_AES_128_CCM_8_SHA256
|
||||||
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-"
|
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-"
|
||||||
"AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-"
|
"AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-"
|
||||||
"SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-"
|
"SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-"
|
||||||
|
@ -61,6 +79,13 @@ constexpr char DEFAULT_CIPHER_LIST[] =
|
||||||
"SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-"
|
"SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-"
|
||||||
"SHA:DES-CBC3-SHA:!DSS";
|
"SHA:DES-CBC3-SHA:!DSS";
|
||||||
|
|
||||||
|
constexpr auto NGHTTP2_TLS_MIN_VERSION = TLS1_VERSION;
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
constexpr auto NGHTTP2_TLS_MAX_VERSION = TLS1_3_VERSION;
|
||||||
|
#else // !TLS1_3_VERSION
|
||||||
|
constexpr auto NGHTTP2_TLS_MAX_VERSION = TLS1_2_VERSION;
|
||||||
|
#endif // !TLS1_3_VERSION
|
||||||
|
|
||||||
const char *get_tls_protocol(SSL *ssl);
|
const char *get_tls_protocol(SSL *ssl);
|
||||||
|
|
||||||
struct TLSSessionInfo {
|
struct TLSSessionInfo {
|
||||||
|
@ -91,6 +116,10 @@ bool check_http2_requirement(SSL *ssl);
|
||||||
// Initializes OpenSSL library
|
// Initializes OpenSSL library
|
||||||
void libssl_init();
|
void libssl_init();
|
||||||
|
|
||||||
|
// Sets TLS min and max versions to |ssl_ctx|. This function returns
|
||||||
|
// 0 if it succeeds, or -1.
|
||||||
|
int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max);
|
||||||
|
|
||||||
} // namespace ssl
|
} // namespace ssl
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
Loading…
Reference in New Issue