Build without HTTP/3 support
This commit is contained in:
parent
f46984d218
commit
4eced8a393
|
@ -448,6 +448,10 @@ foreach(name
|
||||||
configure_file("${name}.in" "${name}" @ONLY)
|
configure_file("${name}.in" "${name}" @ONLY)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
add_definitions(-D__APPLE_USE_RFC_3542)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
||||||
)
|
)
|
||||||
|
|
78
configure.ac
78
configure.ac
|
@ -107,6 +107,11 @@ AC_ARG_ENABLE([lib-only],
|
||||||
[Build libnghttp2 only. This is a short hand for --disable-app --disable-examples --disable-hpack-tools --disable-python-bindings])],
|
[Build libnghttp2 only. This is a short hand for --disable-app --disable-examples --disable-hpack-tools --disable-python-bindings])],
|
||||||
[request_lib_only=$enableval], [request_lib_only=no])
|
[request_lib_only=$enableval], [request_lib_only=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([http3],
|
||||||
|
[AS_HELP_STRING([--enable-http3],
|
||||||
|
[(EXPERIMENTAL) Enable HTTP/3. This requires ngtcp2, nghttp3, and a custom OpenSSL.])],
|
||||||
|
[request_http3=$enableval], [request_http3=no])
|
||||||
|
|
||||||
AC_ARG_WITH([libxml2],
|
AC_ARG_WITH([libxml2],
|
||||||
[AS_HELP_STRING([--with-libxml2],
|
[AS_HELP_STRING([--with-libxml2],
|
||||||
[Use libxml2 [default=check]])],
|
[Use libxml2 [default=check]])],
|
||||||
|
@ -172,6 +177,16 @@ AC_ARG_WITH([cython],
|
||||||
[Use cython in given PATH])],
|
[Use cython in given PATH])],
|
||||||
[cython_path=$withval], [])
|
[cython_path=$withval], [])
|
||||||
|
|
||||||
|
AC_ARG_WITH([libngtcp2],
|
||||||
|
[AS_HELP_STRING([--with-libngtcp2],
|
||||||
|
[Use libngtcp2 [default=check]])],
|
||||||
|
[request_libngtcp2=$withval], [request_libngtcp2=check])
|
||||||
|
|
||||||
|
AC_ARG_WITH([libnghttp3],
|
||||||
|
[AS_HELP_STRING([--with-libnghttp3],
|
||||||
|
[Use libnghttp3 [default=check]])],
|
||||||
|
[request_libnghttp3=$withval], [request_libnghttp3=check])
|
||||||
|
|
||||||
dnl Define variables
|
dnl Define variables
|
||||||
AC_ARG_VAR([CYTHON], [the Cython executable])
|
AC_ARG_VAR([CYTHON], [the Cython executable])
|
||||||
|
|
||||||
|
@ -334,6 +349,13 @@ case "$host_os" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
case "${build}" in
|
||||||
|
*-apple-darwin*)
|
||||||
|
EXTRA_DEFS="-D__APPLE_USE_RFC_3542"
|
||||||
|
AC_SUBST([EXTRA_DEFS])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# zlib
|
# zlib
|
||||||
have_zlib=no
|
have_zlib=no
|
||||||
if test "x${request_zlib}" != "xno"; then
|
if test "x${request_zlib}" != "xno"; then
|
||||||
|
@ -455,26 +477,50 @@ if test "x${request_libcares}" = "xyes" &&
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ngtcp2 (for src)
|
# ngtcp2 (for src)
|
||||||
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 0.0.0], [have_libngtcp2=yes],
|
have_libngtcp2=no
|
||||||
|
if test "x${request_libngtcp2}" != "xno"; then
|
||||||
|
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 0.0.0], [have_libngtcp2=yes],
|
||||||
[have_libngtcp2=no])
|
[have_libngtcp2=no])
|
||||||
if test "x${have_libngtcp2}" = "xno"; then
|
if test "x${have_libngtcp2}" = "xno"; then
|
||||||
AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
|
AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x${request_libngtcp2}" = "xyes" &&
|
||||||
|
test "x${have_libngtcp2}" != "xyes"; then
|
||||||
|
AC_MSG_ERROR([libngtcp2 was requested (--with-libngtcp2) but not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ngtcp2_crypto_openssl (for src)
|
# ngtcp2_crypto_openssl (for src)
|
||||||
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OPENSSL],
|
have_libngtcp2_crypto_openssl=no
|
||||||
|
if test "x${request_libngtcp2}" != "xno"; then
|
||||||
|
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OPENSSL],
|
||||||
[libngtcp2_crypto_openssl >= 0.0.0],
|
[libngtcp2_crypto_openssl >= 0.0.0],
|
||||||
[have_libngtcp2_crypto_openssl=yes],
|
[have_libngtcp2_crypto_openssl=yes],
|
||||||
[have_libngtcp2_crypto_openssl=no])
|
[have_libngtcp2_crypto_openssl=no])
|
||||||
if test "x${have_libngtcp2_crypto_openssl}" = "xno"; then
|
if test "x${have_libngtcp2_crypto_openssl}" = "xno"; then
|
||||||
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS)
|
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x${request_libngtcp2}" = "xyes" &&
|
||||||
|
test "x${have_libngtcp2_crypto_openssl}" != "xyes"; then
|
||||||
|
AC_MSG_ERROR([libngtcp2_crypto_openssl was requested (--with-libngtcp2) but not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# nghttp3 (for src)
|
# nghttp3 (for src)
|
||||||
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 0.0.0], [have_libnghttp3=yes],
|
have_libnghttp3=no
|
||||||
|
if test "x${request_libnghttp3}" != "xno"; then
|
||||||
|
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 0.0.0], [have_libnghttp3=yes],
|
||||||
[have_libnghttp3=no])
|
[have_libnghttp3=no])
|
||||||
if test "x${have_libnghttp3}" = "xno"; then
|
if test "x${have_libnghttp3}" = "xno"; then
|
||||||
AC_MSG_NOTICE($LIBNGHTTP3_PKT_ERRORS)
|
AC_MSG_NOTICE($LIBNGHTTP3_PKG_ERRORS)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x${request_libnghttp3}" = "xyes" &&
|
||||||
|
test "x${have_libnghttp3}" != "xyes"; then
|
||||||
|
AC_MSG_ERROR([libnghttp3 was requested (--with-libnghttp3) but not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# libevent_openssl (for examples)
|
# libevent_openssl (for examples)
|
||||||
|
@ -621,6 +667,23 @@ fi
|
||||||
|
|
||||||
AM_CONDITIONAL([ENABLE_APP], [ test "x${enable_app}" = "xyes" ])
|
AM_CONDITIONAL([ENABLE_APP], [ test "x${enable_app}" = "xyes" ])
|
||||||
|
|
||||||
|
# Check HTTP/3 support
|
||||||
|
enable_http3=no
|
||||||
|
if test "x${request_http3}" != "xno" &&
|
||||||
|
test "x${have_libngtcp2}" = "xyes" &&
|
||||||
|
test "x${have_libngtcp2_crypto_openssl}" = "xyes" &&
|
||||||
|
test "x${have_libnghttp3}" = "xyes"; then
|
||||||
|
enable_http3=yes
|
||||||
|
AC_DEFINE([ENABLE_HTTP3], [1], [Define to 1 if HTTP/3 is enabled.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x${request_http3}" = "xyes" &&
|
||||||
|
test "x${enable_http3}" != "xyes"; then
|
||||||
|
AC_MSG_ERROR([HTTP/3 was requested (--enable-http3) but dependencies are not met.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL([ENABLE_HTTP3], [ test "x${enable_http3}" = "xyes" ])
|
||||||
|
|
||||||
enable_hpack_tools=no
|
enable_hpack_tools=no
|
||||||
# HPACK tools requires jansson
|
# HPACK tools requires jansson
|
||||||
if test "x${request_hpack_tools}" != "xno" &&
|
if test "x${request_hpack_tools}" != "xno" &&
|
||||||
|
@ -1058,4 +1121,5 @@ AC_MSG_NOTICE([summary of build options:
|
||||||
Examples: ${enable_examples}
|
Examples: ${enable_examples}
|
||||||
Python bindings:${enable_python_bindings}
|
Python bindings:${enable_python_bindings}
|
||||||
Threading: ${enable_threads}
|
Threading: ${enable_threads}
|
||||||
|
HTTP/3 (EXPERIMENTAL): ${enable_http3}
|
||||||
])
|
])
|
||||||
|
|
|
@ -51,6 +51,7 @@ AM_CPPFLAGS = \
|
||||||
@LIBNGTCP2_CFLAGS@ \
|
@LIBNGTCP2_CFLAGS@ \
|
||||||
@JANSSON_CFLAGS@ \
|
@JANSSON_CFLAGS@ \
|
||||||
@ZLIB_CFLAGS@ \
|
@ZLIB_CFLAGS@ \
|
||||||
|
@EXTRA_DEFS@ \
|
||||||
@DEFS@
|
@DEFS@
|
||||||
AM_LDFLAGS = @LIBTOOL_LDFLAGS@
|
AM_LDFLAGS = @LIBTOOL_LDFLAGS@
|
||||||
|
|
||||||
|
@ -103,10 +104,14 @@ h2load_SOURCES = util.cc util.h \
|
||||||
tls.cc tls.h \
|
tls.cc tls.h \
|
||||||
h2load_session.h \
|
h2load_session.h \
|
||||||
h2load_http2_session.cc h2load_http2_session.h \
|
h2load_http2_session.cc h2load_http2_session.h \
|
||||||
h2load_http1_session.cc h2load_http1_session.h \
|
h2load_http1_session.cc h2load_http1_session.h
|
||||||
|
|
||||||
|
if ENABLE_HTTP3
|
||||||
|
h2load_SOURCES += \
|
||||||
h2load_http3_session.cc h2load_http3_session.h \
|
h2load_http3_session.cc h2load_http3_session.h \
|
||||||
h2load_quic.cc h2load_quic.h \
|
h2load_quic.cc h2load_quic.h \
|
||||||
quic.cc quic.h
|
quic.cc quic.h
|
||||||
|
endif # ENABLE_HTTP3
|
||||||
|
|
||||||
NGHTTPX_SRCS = \
|
NGHTTPX_SRCS = \
|
||||||
util.cc util.h http2.cc http2.h timegm.c timegm.h base64.h \
|
util.cc util.h http2.cc http2.h timegm.c timegm.h base64.h \
|
||||||
|
@ -153,12 +158,6 @@ NGHTTPX_SRCS = \
|
||||||
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
||||||
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
||||||
shrpx_dns_tracker.cc shrpx_dns_tracker.h \
|
shrpx_dns_tracker.cc shrpx_dns_tracker.h \
|
||||||
shrpx_quic.cc shrpx_quic.h \
|
|
||||||
shrpx_quic_listener.cc shrpx_quic_listener.h \
|
|
||||||
shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
|
|
||||||
shrpx_http3_upstream.cc shrpx_http3_upstream.h \
|
|
||||||
http3.cc http3.h \
|
|
||||||
quic.cc quic.h \
|
|
||||||
buffer.h memchunk.h template.h allocator.h \
|
buffer.h memchunk.h template.h allocator.h \
|
||||||
xsi_strerror.c xsi_strerror.h
|
xsi_strerror.c xsi_strerror.h
|
||||||
|
|
||||||
|
@ -171,6 +170,16 @@ NGHTTPX_SRCS += \
|
||||||
shrpx_mruby_module_response.cc shrpx_mruby_module_response.h
|
shrpx_mruby_module_response.cc shrpx_mruby_module_response.h
|
||||||
endif # HAVE_MRUBY
|
endif # HAVE_MRUBY
|
||||||
|
|
||||||
|
if ENABLE_HTTP3
|
||||||
|
NGHTTPX_SRCS += \
|
||||||
|
shrpx_quic.cc shrpx_quic.h \
|
||||||
|
shrpx_quic_listener.cc shrpx_quic_listener.h \
|
||||||
|
shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
|
||||||
|
shrpx_http3_upstream.cc shrpx_http3_upstream.h \
|
||||||
|
http3.cc http3.h \
|
||||||
|
quic.cc quic.h
|
||||||
|
endif # ENABLE_HTTP3
|
||||||
|
|
||||||
noinst_LIBRARIES = libnghttpx.a
|
noinst_LIBRARIES = libnghttpx.a
|
||||||
libnghttpx_a_SOURCES = ${NGHTTPX_SRCS}
|
libnghttpx_a_SOURCES = ${NGHTTPX_SRCS}
|
||||||
libnghttpx_a_CPPFLAGS = ${AM_CPPFLAGS}
|
libnghttpx_a_CPPFLAGS = ${AM_CPPFLAGS}
|
||||||
|
|
|
@ -50,14 +50,18 @@
|
||||||
|
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#include <ngtcp2/ngtcp2.h>
|
#ifdef ENABLE_HTTP3
|
||||||
|
# include <ngtcp2/ngtcp2.h>
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#include "url-parser/url_parser.h"
|
#include "url-parser/url_parser.h"
|
||||||
|
|
||||||
#include "h2load_http1_session.h"
|
#include "h2load_http1_session.h"
|
||||||
#include "h2load_http2_session.h"
|
#include "h2load_http2_session.h"
|
||||||
#include "h2load_http3_session.h"
|
#ifdef ENABLE_HTTP3
|
||||||
#include "h2load_quic.h"
|
# include "h2load_http3_session.h"
|
||||||
|
# include "h2load_quic.h"
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
#include "http2.h"
|
#include "http2.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -141,8 +145,12 @@ bool Config::is_timing_based_mode() const { return (this->duration > 0); }
|
||||||
bool Config::has_base_uri() const { return (!this->base_uri.empty()); }
|
bool Config::has_base_uri() const { return (!this->base_uri.empty()); }
|
||||||
bool Config::rps_enabled() const { return this->rps > 0.0; }
|
bool Config::rps_enabled() const { return this->rps > 0.0; }
|
||||||
bool Config::is_quic() const {
|
bool Config::is_quic() const {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
return !npn_list.empty() &&
|
return !npn_list.empty() &&
|
||||||
(npn_list[0] == NGHTTP3_ALPN_H3 || npn_list[0] == "\x5h3-29");
|
(npn_list[0] == NGHTTP3_ALPN_H3 || npn_list[0] == "\x5h3-29");
|
||||||
|
#else // !ENABLE_HTTP3
|
||||||
|
return false;
|
||||||
|
#endif // !ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
Config config;
|
Config config;
|
||||||
|
|
||||||
|
@ -435,7 +443,9 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
|
||||||
cstat{},
|
cstat{},
|
||||||
worker(worker),
|
worker(worker),
|
||||||
ssl(nullptr),
|
ssl(nullptr),
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic{},
|
quic{},
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
next_addr(config.addrs),
|
next_addr(config.addrs),
|
||||||
current_addr(nullptr),
|
current_addr(nullptr),
|
||||||
reqidx(0),
|
reqidx(0),
|
||||||
|
@ -478,16 +488,20 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
|
||||||
ev_timer_init(&rps_watcher, rps_cb, 0., 0.);
|
ev_timer_init(&rps_watcher, rps_cb, 0., 0.);
|
||||||
rps_watcher.data = this;
|
rps_watcher.data = this;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
ev_timer_init(&quic.pkt_timer, quic_pkt_timeout_cb, 0., 0.);
|
ev_timer_init(&quic.pkt_timer, quic_pkt_timeout_cb, 0., 0.);
|
||||||
quic.pkt_timer.data = this;
|
quic.pkt_timer.data = this;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client() {
|
Client::~Client() {
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
quic_free();
|
quic_free();
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
SSL_free(ssl);
|
SSL_free(ssl);
|
||||||
|
@ -504,6 +518,7 @@ int Client::make_socket(addrinfo *addr) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
fd = util::create_nonblock_udp_socket(addr->ai_family);
|
fd = util::create_nonblock_udp_socket(addr->ai_family);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -528,6 +543,7 @@ int Client::make_socket(addrinfo *addr) {
|
||||||
std::cerr << "quic_init failed" << std::endl;
|
std::cerr << "quic_init failed" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
} else {
|
} else {
|
||||||
fd = util::create_nonblock_socket(addr->ai_family);
|
fd = util::create_nonblock_socket(addr->ai_family);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
@ -614,10 +630,12 @@ int Client::connect() {
|
||||||
ev_io_start(worker->loop, &wev);
|
ev_io_start(worker->loop, &wev);
|
||||||
|
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
ev_io_start(worker->loop, &rev);
|
ev_io_start(worker->loop, &rev);
|
||||||
|
|
||||||
readfn = &Client::read_quic;
|
readfn = &Client::read_quic;
|
||||||
writefn = &Client::write_quic;
|
writefn = &Client::write_quic;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
} else {
|
} else {
|
||||||
writefn = &Client::connected;
|
writefn = &Client::connected;
|
||||||
}
|
}
|
||||||
|
@ -676,11 +694,15 @@ void Client::fail() {
|
||||||
void Client::disconnect() {
|
void Client::disconnect() {
|
||||||
record_client_end_time();
|
record_client_end_time();
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
quic_close_connection();
|
quic_close_connection();
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
ev_timer_stop(worker->loop, &quic.pkt_timer);
|
ev_timer_stop(worker->loop, &quic.pkt_timer);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
ev_timer_stop(worker->loop, &conn_inactivity_watcher);
|
ev_timer_stop(worker->loop, &conn_inactivity_watcher);
|
||||||
ev_timer_stop(worker->loop, &conn_active_watcher);
|
ev_timer_stop(worker->loop, &conn_active_watcher);
|
||||||
ev_timer_stop(worker->loop, &rps_watcher);
|
ev_timer_stop(worker->loop, &rps_watcher);
|
||||||
|
@ -843,9 +865,11 @@ void Client::report_app_info() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::terminate_session() {
|
void Client::terminate_session() {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
quic.close_requested = true;
|
quic.close_requested = true;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
if (session) {
|
if (session) {
|
||||||
session->terminate();
|
session->terminate();
|
||||||
}
|
}
|
||||||
|
@ -1047,11 +1071,13 @@ int Client::connection_made() {
|
||||||
if (next_proto) {
|
if (next_proto) {
|
||||||
auto proto = StringRef{next_proto, next_proto_len};
|
auto proto = StringRef{next_proto, next_proto_len};
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
assert(session);
|
assert(session);
|
||||||
if (!util::streq(StringRef{&NGHTTP3_ALPN_H3[1]}, proto) &&
|
if (!util::streq(StringRef{&NGHTTP3_ALPN_H3[1]}, proto) &&
|
||||||
!util::streq_l("h3-29", proto)) {
|
!util::streq_l("h3-29", proto)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
} else if (util::check_h2_is_selected(proto)) {
|
} else if (util::check_h2_is_selected(proto)) {
|
||||||
session = std::make_unique<Http2Session>(this);
|
session = std::make_unique<Http2Session>(this);
|
||||||
} else if (util::streq(NGHTTP2_H1_1, proto)) {
|
} else if (util::streq(NGHTTP2_H1_1, proto)) {
|
||||||
|
@ -1377,6 +1403,7 @@ int Client::write_tls() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
int Client::write_udp(const sockaddr *addr, socklen_t addrlen,
|
int Client::write_udp(const sockaddr *addr, socklen_t addrlen,
|
||||||
const uint8_t *data, size_t datalen, size_t gso_size) {
|
const uint8_t *data, size_t datalen, size_t gso_size) {
|
||||||
iovec msg_iov;
|
iovec msg_iov;
|
||||||
|
@ -1389,7 +1416,7 @@ int Client::write_udp(const sockaddr *addr, socklen_t addrlen,
|
||||||
msg.msg_iov = &msg_iov;
|
msg.msg_iov = &msg_iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
|
|
||||||
#ifdef UDP_SEGMENT
|
# ifdef UDP_SEGMENT
|
||||||
std::array<uint8_t, CMSG_SPACE(sizeof(uint16_t))> msg_ctrl{};
|
std::array<uint8_t, CMSG_SPACE(sizeof(uint16_t))> msg_ctrl{};
|
||||||
if (gso_size && datalen > gso_size) {
|
if (gso_size && datalen > gso_size) {
|
||||||
msg.msg_control = msg_ctrl.data();
|
msg.msg_control = msg_ctrl.data();
|
||||||
|
@ -1401,7 +1428,7 @@ int Client::write_udp(const sockaddr *addr, socklen_t addrlen,
|
||||||
cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
|
cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
|
||||||
*(reinterpret_cast<uint16_t *>(CMSG_DATA(cm))) = gso_size;
|
*(reinterpret_cast<uint16_t *>(CMSG_DATA(cm))) = gso_size;
|
||||||
}
|
}
|
||||||
#endif // UDP_SEGMENT
|
# endif // UDP_SEGMENT
|
||||||
|
|
||||||
auto nwrite = sendmsg(fd, &msg, 0);
|
auto nwrite = sendmsg(fd, &msg, 0);
|
||||||
if (nwrite < 0) {
|
if (nwrite < 0) {
|
||||||
|
@ -1414,6 +1441,7 @@ int Client::write_udp(const sockaddr *addr, socklen_t addrlen,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
void Client::record_request_time(RequestStat *req_stat) {
|
void Client::record_request_time(RequestStat *req_stat) {
|
||||||
req_stat->request_time = std::chrono::steady_clock::now();
|
req_stat->request_time = std::chrono::steady_clock::now();
|
||||||
|
@ -2740,7 +2768,9 @@ int main(int argc, char **argv) {
|
||||||
<< "Warning: --qlog-file-base: only effective in quic, ignoring."
|
<< "Warning: --qlog-file-base: only effective in quic, ignoring."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
config.qlog_file_base = qlog_base;
|
config.qlog_file_base = qlog_base;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2764,8 +2794,10 @@ int main(int argc, char **argv) {
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
} else if (nghttp2::tls::ssl_ctx_set_proto_versions(
|
} else if (nghttp2::tls::ssl_ctx_set_proto_versions(
|
||||||
ssl_ctx, nghttp2::tls::NGHTTP2_TLS_MIN_VERSION,
|
ssl_ctx, nghttp2::tls::NGHTTP2_TLS_MIN_VERSION,
|
||||||
nghttp2::tls::NGHTTP2_TLS_MAX_VERSION) != 0) {
|
nghttp2::tls::NGHTTP2_TLS_MAX_VERSION) != 0) {
|
||||||
|
@ -2780,12 +2812,14 @@ int main(int argc, char **argv) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENSSL_1_1_1_API
|
||||||
if (SSL_CTX_set_ciphersuites(ssl_ctx, config.tls13_ciphers.c_str()) == 0) {
|
if (SSL_CTX_set_ciphersuites(ssl_ctx, config.tls13_ciphers.c_str()) == 0) {
|
||||||
std::cerr << "SSL_CTX_set_ciphersuites with " << config.tls13_ciphers
|
std::cerr << "SSL_CTX_set_ciphersuites with " << config.tls13_ciphers
|
||||||
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr)
|
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
#endif // OPENSSL_1_1_1_API
|
||||||
|
|
||||||
if (SSL_CTX_set1_groups_list(ssl_ctx, config.groups.c_str()) != 1) {
|
if (SSL_CTX_set1_groups_list(ssl_ctx, config.groups.c_str()) != 1) {
|
||||||
std::cerr << "SSL_CTX_set1_groups_list failed" << std::endl;
|
std::cerr << "SSL_CTX_set1_groups_list failed" << std::endl;
|
||||||
|
@ -2806,6 +2840,7 @@ int main(int argc, char **argv) {
|
||||||
SSL_CTX_set_alpn_protos(ssl_ctx, proto_list.data(), proto_list.size());
|
SSL_CTX_set_alpn_protos(ssl_ctx, proto_list.data(), proto_list.size());
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
#if OPENSSL_1_1_1_API
|
||||||
auto keylog_filename = getenv("SSLKEYLOGFILE");
|
auto keylog_filename = getenv("SSLKEYLOGFILE");
|
||||||
if (keylog_filename) {
|
if (keylog_filename) {
|
||||||
keylog_file.open(keylog_filename, std::ios_base::app);
|
keylog_file.open(keylog_filename, std::ios_base::app);
|
||||||
|
@ -2813,6 +2848,7 @@ int main(int argc, char **argv) {
|
||||||
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
|
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // OPENSSL_1_1_1_API
|
||||||
|
|
||||||
std::string user_agent = "h2load nghttp2/" NGHTTP2_VERSION;
|
std::string user_agent = "h2load nghttp2/" NGHTTP2_VERSION;
|
||||||
Headers shared_nva;
|
Headers shared_nva;
|
||||||
|
@ -3093,10 +3129,12 @@ traffic: )" << util::utos_funit(stats.bytes_total)
|
||||||
<< ") headers (space savings " << header_space_savings * 100
|
<< ") headers (space savings " << header_space_savings * 100
|
||||||
<< "%), " << util::utos_funit(stats.bytes_body) << "B ("
|
<< "%), " << util::utos_funit(stats.bytes_body) << "B ("
|
||||||
<< stats.bytes_body << R"() data)" << std::endl;
|
<< stats.bytes_body << R"() data)" << std::endl;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
if (config.is_quic()) {
|
if (config.is_quic()) {
|
||||||
std::cout << "UDP datagram: " << stats.udp_dgram_sent << " sent, "
|
std::cout << "UDP datagram: " << stats.udp_dgram_sent << " sent, "
|
||||||
<< stats.udp_dgram_recv << " received" << std::endl;
|
<< stats.udp_dgram_recv << " received" << std::endl;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
std::cout
|
std::cout
|
||||||
<< R"( min max mean sd +/- sd
|
<< R"( min max mean sd +/- sd
|
||||||
time for request: )"
|
time for request: )"
|
||||||
|
|
14
src/h2load.h
14
src/h2load.h
|
@ -45,15 +45,19 @@
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#include <ngtcp2/ngtcp2.h>
|
#ifdef ENABLE_HTTP3
|
||||||
#include <ngtcp2/ngtcp2_crypto.h>
|
# include <ngtcp2/ngtcp2.h>
|
||||||
|
# include <ngtcp2/ngtcp2_crypto.h>
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#include "http2.h"
|
#include "http2.h"
|
||||||
#include "quic.h"
|
#ifdef ENABLE_HTTP3
|
||||||
|
# include "quic.h"
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
#include "memchunk.h"
|
#include "memchunk.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
|
||||||
|
@ -327,6 +331,7 @@ struct Client {
|
||||||
std::function<int(Client &)> readfn, writefn;
|
std::function<int(Client &)> readfn, writefn;
|
||||||
Worker *worker;
|
Worker *worker;
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
struct {
|
struct {
|
||||||
ev_timer pkt_timer;
|
ev_timer pkt_timer;
|
||||||
ngtcp2_conn *conn;
|
ngtcp2_conn *conn;
|
||||||
|
@ -335,6 +340,7 @@ struct Client {
|
||||||
bool close_requested;
|
bool close_requested;
|
||||||
FILE *qlog_file;
|
FILE *qlog_file;
|
||||||
} quic;
|
} quic;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
ev_timer request_timeout_watcher;
|
ev_timer request_timeout_watcher;
|
||||||
addrinfo *next_addr;
|
addrinfo *next_addr;
|
||||||
// Address for the current address. When try_new_connection() is
|
// Address for the current address. When try_new_connection() is
|
||||||
|
@ -447,6 +453,7 @@ struct Client {
|
||||||
|
|
||||||
void signal_write();
|
void signal_write();
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
// QUIC
|
// QUIC
|
||||||
int quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
|
int quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
|
||||||
const sockaddr *remote_addr, socklen_t remote_addrlen);
|
const sockaddr *remote_addr, socklen_t remote_addrlen);
|
||||||
|
@ -475,6 +482,7 @@ struct Client {
|
||||||
int quic_pkt_timeout();
|
int quic_pkt_timeout();
|
||||||
void quic_restart_pkt_timer();
|
void quic_restart_pkt_timer();
|
||||||
void quic_write_qlog(const void *data, size_t datalen);
|
void quic_write_qlog(const void *data, size_t datalen);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace h2load
|
} // namespace h2load
|
||||||
|
|
|
@ -1548,6 +1548,7 @@ void fill_default_config(Config *config) {
|
||||||
downstreamconf.option, downstreamconf.encoder_dynamic_table_size);
|
downstreamconf.option, downstreamconf.encoder_dynamic_table_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
auto &quicconf = config->quic;
|
auto &quicconf = config->quic;
|
||||||
{
|
{
|
||||||
quicconf.timeout.idle = 30_s;
|
quicconf.timeout.idle = 30_s;
|
||||||
|
@ -1560,6 +1561,7 @@ void fill_default_config(Config *config) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
auto &loggingconf = config->logging;
|
auto &loggingconf = config->logging;
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,9 @@
|
||||||
#include "shrpx_api_downstream_connection.h"
|
#include "shrpx_api_downstream_connection.h"
|
||||||
#include "shrpx_health_monitor_downstream_connection.h"
|
#include "shrpx_health_monitor_downstream_connection.h"
|
||||||
#include "shrpx_null_downstream_connection.h"
|
#include "shrpx_null_downstream_connection.h"
|
||||||
#include "shrpx_http3_upstream.h"
|
#ifdef ENABLE_HTTP3
|
||||||
|
# include "shrpx_http3_upstream.h"
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
#include "shrpx_log.h"
|
#include "shrpx_log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
@ -287,6 +289,7 @@ int ClientHandler::write_tls() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
int ClientHandler::read_quic(const UpstreamAddr *faddr,
|
int ClientHandler::read_quic(const UpstreamAddr *faddr,
|
||||||
const Address &remote_addr,
|
const Address &remote_addr,
|
||||||
const Address &local_addr, const uint8_t *data,
|
const Address &local_addr, const uint8_t *data,
|
||||||
|
@ -297,6 +300,7 @@ int ClientHandler::read_quic(const UpstreamAddr *faddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClientHandler::write_quic() { return upstream_->on_write(); }
|
int ClientHandler::write_quic() { return upstream_->on_write(); }
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
int ClientHandler::upstream_noop() { return 0; }
|
int ClientHandler::upstream_noop() { return 0; }
|
||||||
|
|
||||||
|
@ -509,12 +513,14 @@ void ClientHandler::setup_upstream_io_callback() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
void ClientHandler::setup_http3_upstream(
|
void ClientHandler::setup_http3_upstream(
|
||||||
std::unique_ptr<Http3Upstream> &&upstream) {
|
std::unique_ptr<Http3Upstream> &&upstream) {
|
||||||
upstream_ = std::move(upstream);
|
upstream_ = std::move(upstream);
|
||||||
alpn_ = StringRef::from_lit("h3");
|
alpn_ = StringRef::from_lit("h3");
|
||||||
write_ = &ClientHandler::write_quic;
|
write_ = &ClientHandler::write_quic;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
ClientHandler::~ClientHandler() {
|
ClientHandler::~ClientHandler() {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
|
|
@ -53,7 +53,9 @@ class Downstream;
|
||||||
struct WorkerStat;
|
struct WorkerStat;
|
||||||
struct DownstreamAddrGroup;
|
struct DownstreamAddrGroup;
|
||||||
struct DownstreamAddr;
|
struct DownstreamAddr;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
class Http3Upstream;
|
class Http3Upstream;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
class ClientHandler {
|
class ClientHandler {
|
||||||
public:
|
public:
|
||||||
|
@ -71,9 +73,6 @@ public:
|
||||||
int read_tls();
|
int read_tls();
|
||||||
int write_tls();
|
int write_tls();
|
||||||
|
|
||||||
int read_quic(const UpstreamAddr *faddr, const Address &remote_addr,
|
|
||||||
const Address &local_addr, const uint8_t *data, size_t datalen);
|
|
||||||
|
|
||||||
int upstream_noop();
|
int upstream_noop();
|
||||||
int upstream_read();
|
int upstream_read();
|
||||||
int upstream_http2_connhd_read();
|
int upstream_http2_connhd_read();
|
||||||
|
@ -147,8 +146,12 @@ public:
|
||||||
|
|
||||||
void setup_upstream_io_callback();
|
void setup_upstream_io_callback();
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
void setup_http3_upstream(std::unique_ptr<Http3Upstream> &&upstream);
|
void setup_http3_upstream(std::unique_ptr<Http3Upstream> &&upstream);
|
||||||
|
int read_quic(const UpstreamAddr *faddr, const Address &remote_addr,
|
||||||
|
const Address &local_addr, const uint8_t *data, size_t datalen);
|
||||||
int write_quic();
|
int write_quic();
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
// Returns string suitable for use in "by" parameter of Forwarded
|
// Returns string suitable for use in "by" parameter of Forwarded
|
||||||
// header field.
|
// header field.
|
||||||
|
|
|
@ -821,7 +821,11 @@ int parse_upstream_params(UpstreamParams &out, const StringRef &src_params) {
|
||||||
} else if (util::strieq_l("proxyproto", param)) {
|
} else if (util::strieq_l("proxyproto", param)) {
|
||||||
out.proxyproto = true;
|
out.proxyproto = true;
|
||||||
} else if (util::strieq_l("quic", param)) {
|
} else if (util::strieq_l("quic", param)) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
out.quic = true;
|
out.quic = true;
|
||||||
|
#else // !ENABLE_HTTP3
|
||||||
|
LOG(ERROR) << "quic: QUIC is disabled at compile time";
|
||||||
|
#endif // !ENABLE_HTTP3
|
||||||
} else if (!param.empty()) {
|
} else if (!param.empty()) {
|
||||||
LOG(ERROR) << "frontend: " << param << ": unknown keyword";
|
LOG(ERROR) << "frontend: " << param << ": unknown keyword";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2674,8 +2678,12 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||||
apiconf.enabled = true;
|
apiconf.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
auto &addrs = params.quic ? config->conn.quic_listener.addrs
|
auto &addrs = params.quic ? config->conn.quic_listener.addrs
|
||||||
: config->conn.listener.addrs;
|
: config->conn.listener.addrs;
|
||||||
|
#else // !ENABLE_HTTP3
|
||||||
|
auto &addrs = config->conn.listener.addrs;
|
||||||
|
#endif // !ENABLE_HTTP3
|
||||||
|
|
||||||
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
||||||
auto path = std::begin(optarg) + SHRPX_UNIX_PATH_PREFIX.size();
|
auto path = std::begin(optarg) + SHRPX_UNIX_PATH_PREFIX.size();
|
||||||
|
|
|
@ -704,6 +704,7 @@ struct TLSConfig {
|
||||||
bool no_postpone_early_data;
|
bool no_postpone_early_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
struct QUICConfig {
|
struct QUICConfig {
|
||||||
struct {
|
struct {
|
||||||
std::array<uint8_t, 32> secret;
|
std::array<uint8_t, 32> secret;
|
||||||
|
@ -715,6 +716,7 @@ struct QUICConfig {
|
||||||
bool log;
|
bool log;
|
||||||
} debug;
|
} debug;
|
||||||
};
|
};
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
// custom error page
|
// custom error page
|
||||||
struct ErrorPage {
|
struct ErrorPage {
|
||||||
|
@ -921,9 +923,11 @@ struct ConnectionConfig {
|
||||||
int fastopen;
|
int fastopen;
|
||||||
} listener;
|
} listener;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
struct {
|
struct {
|
||||||
std::vector<UpstreamAddr> addrs;
|
std::vector<UpstreamAddr> addrs;
|
||||||
} quic_listener;
|
} quic_listener;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
|
@ -968,7 +972,9 @@ struct Config {
|
||||||
http{},
|
http{},
|
||||||
http2{},
|
http2{},
|
||||||
tls{},
|
tls{},
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic{},
|
quic{},
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
logging{},
|
logging{},
|
||||||
conn{},
|
conn{},
|
||||||
api{},
|
api{},
|
||||||
|
@ -986,7 +992,8 @@ struct Config {
|
||||||
single_process{false},
|
single_process{false},
|
||||||
single_thread{false},
|
single_thread{false},
|
||||||
ignore_per_pattern_mruby_error{false},
|
ignore_per_pattern_mruby_error{false},
|
||||||
ev_loop_flags{0} {}
|
ev_loop_flags{0} {
|
||||||
|
}
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
Config(Config &&) = delete;
|
Config(Config &&) = delete;
|
||||||
|
@ -1002,7 +1009,9 @@ struct Config {
|
||||||
HttpConfig http;
|
HttpConfig http;
|
||||||
Http2Config http2;
|
Http2Config http2;
|
||||||
TLSConfig tls;
|
TLSConfig tls;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
QUICConfig quic;
|
QUICConfig quic;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
LoggingConfig logging;
|
LoggingConfig logging;
|
||||||
ConnectionConfig conn;
|
ConnectionConfig conn;
|
||||||
APIConfig api;
|
APIConfig api;
|
||||||
|
|
|
@ -156,6 +156,7 @@ ConnectionHandler::~ConnectionHandler() {
|
||||||
ev_timer_stop(loop_, &ocsp_timer_);
|
ev_timer_stop(loop_, &ocsp_timer_);
|
||||||
ev_timer_stop(loop_, &disable_acceptor_timer_);
|
ev_timer_stop(loop_, &disable_acceptor_timer_);
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
for (auto ssl_ctx : quic_all_ssl_ctx_) {
|
for (auto ssl_ctx : quic_all_ssl_ctx_) {
|
||||||
if (ssl_ctx == nullptr) {
|
if (ssl_ctx == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -166,6 +167,7 @@ ConnectionHandler::~ConnectionHandler() {
|
||||||
delete tls_ctx_data;
|
delete tls_ctx_data;
|
||||||
SSL_CTX_free(ssl_ctx);
|
SSL_CTX_free(ssl_ctx);
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
for (auto ssl_ctx : all_ssl_ctx_) {
|
for (auto ssl_ctx : all_ssl_ctx_) {
|
||||||
auto tls_ctx_data =
|
auto tls_ctx_data =
|
||||||
|
@ -221,14 +223,16 @@ int ConnectionHandler::create_single_worker() {
|
||||||
#endif // HAVE_NEVERBLEED
|
#endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic_cert_tree_ = tls::create_cert_lookup_tree();
|
quic_cert_tree_ = tls::create_cert_lookup_tree();
|
||||||
auto quic_sv_ssl_ctx = tls::setup_quic_server_ssl_context(
|
auto quic_sv_ssl_ctx = tls::setup_quic_server_ssl_context(
|
||||||
quic_all_ssl_ctx_, quic_indexed_ssl_ctx_, quic_cert_tree_.get()
|
quic_all_ssl_ctx_, quic_indexed_ssl_ctx_, quic_cert_tree_.get()
|
||||||
#ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
,
|
,
|
||||||
nb_
|
nb_
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
|
auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
|
||||||
#ifdef HAVE_NEVERBLEED
|
#ifdef HAVE_NEVERBLEED
|
||||||
|
@ -238,7 +242,9 @@ int ConnectionHandler::create_single_worker() {
|
||||||
|
|
||||||
if (cl_ssl_ctx) {
|
if (cl_ssl_ctx) {
|
||||||
all_ssl_ctx_.push_back(cl_ssl_ctx);
|
all_ssl_ctx_.push_back(cl_ssl_ctx);
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic_all_ssl_ctx_.push_back(nullptr);
|
quic_all_ssl_ctx_.push_back(nullptr);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
|
|
||||||
auto config = get_config();
|
auto config = get_config();
|
||||||
|
@ -255,22 +261,29 @@ int ConnectionHandler::create_single_worker() {
|
||||||
tlsconf.cacert, memcachedconf.cert_file,
|
tlsconf.cacert, memcachedconf.cert_file,
|
||||||
memcachedconf.private_key_file, nullptr);
|
memcachedconf.private_key_file, nullptr);
|
||||||
all_ssl_ctx_.push_back(session_cache_ssl_ctx);
|
all_ssl_ctx_.push_back(session_cache_ssl_ctx);
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic_all_ssl_ctx_.push_back(nullptr);
|
quic_all_ssl_ctx_.push_back(nullptr);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
single_worker_ = std::make_unique<Worker>(
|
single_worker_ = std::make_unique<Worker>(
|
||||||
loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
|
loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
|
||||||
quic_sv_ssl_ctx, quic_cert_tree_.get(), ticket_keys_, this,
|
#ifdef ENABLE_HTTP3
|
||||||
config->conn.downstream);
|
quic_sv_ssl_ctx, quic_cert_tree_.get(),
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
ticket_keys_, this, config->conn.downstream);
|
||||||
#ifdef HAVE_MRUBY
|
#ifdef HAVE_MRUBY
|
||||||
if (single_worker_->create_mruby_context() != 0) {
|
if (single_worker_->create_mruby_context() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif // HAVE_MRUBY
|
#endif // HAVE_MRUBY
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
if (single_worker_->setup_quic_server_socket() != 0) {
|
if (single_worker_->setup_quic_server_socket() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -288,6 +301,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
|
||||||
# endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# ifdef ENABLE_HTTP3
|
||||||
quic_cert_tree_ = tls::create_cert_lookup_tree();
|
quic_cert_tree_ = tls::create_cert_lookup_tree();
|
||||||
auto quic_sv_ssl_ctx = tls::setup_quic_server_ssl_context(
|
auto quic_sv_ssl_ctx = tls::setup_quic_server_ssl_context(
|
||||||
quic_all_ssl_ctx_, quic_indexed_ssl_ctx_, quic_cert_tree_.get()
|
quic_all_ssl_ctx_, quic_indexed_ssl_ctx_, quic_cert_tree_.get()
|
||||||
|
@ -296,6 +310,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
|
||||||
nb_
|
nb_
|
||||||
# endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
# endif // ENABLE_HTTP3
|
||||||
|
|
||||||
auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
|
auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
|
||||||
# ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
|
@ -305,7 +320,9 @@ int ConnectionHandler::create_worker_thread(size_t num) {
|
||||||
|
|
||||||
if (cl_ssl_ctx) {
|
if (cl_ssl_ctx) {
|
||||||
all_ssl_ctx_.push_back(cl_ssl_ctx);
|
all_ssl_ctx_.push_back(cl_ssl_ctx);
|
||||||
|
# ifdef ENABLE_HTTP3
|
||||||
quic_all_ssl_ctx_.push_back(nullptr);
|
quic_all_ssl_ctx_.push_back(nullptr);
|
||||||
|
# endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
|
|
||||||
auto config = get_config();
|
auto config = get_config();
|
||||||
|
@ -329,7 +346,9 @@ int ConnectionHandler::create_worker_thread(size_t num) {
|
||||||
tlsconf.cacert, memcachedconf.cert_file,
|
tlsconf.cacert, memcachedconf.cert_file,
|
||||||
memcachedconf.private_key_file, nullptr);
|
memcachedconf.private_key_file, nullptr);
|
||||||
all_ssl_ctx_.push_back(session_cache_ssl_ctx);
|
all_ssl_ctx_.push_back(session_cache_ssl_ctx);
|
||||||
|
# ifdef ENABLE_HTTP3
|
||||||
quic_all_ssl_ctx_.push_back(nullptr);
|
quic_all_ssl_ctx_.push_back(nullptr);
|
||||||
|
# endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,17 +357,22 @@ int ConnectionHandler::create_worker_thread(size_t num) {
|
||||||
|
|
||||||
auto worker = std::make_unique<Worker>(
|
auto worker = std::make_unique<Worker>(
|
||||||
loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
|
loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
|
||||||
quic_sv_ssl_ctx, quic_cert_tree_.get(), ticket_keys_, this,
|
# ifdef ENABLE_HTTP3
|
||||||
config->conn.downstream);
|
quic_sv_ssl_ctx, quic_cert_tree_.get(),
|
||||||
|
# endif // ENABLE_HTTP3
|
||||||
|
ticket_keys_, this, config->conn.downstream);
|
||||||
# ifdef HAVE_MRUBY
|
# ifdef HAVE_MRUBY
|
||||||
if (worker->create_mruby_context() != 0) {
|
if (worker->create_mruby_context() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
# endif // HAVE_MRUBY
|
# endif // HAVE_MRUBY
|
||||||
|
|
||||||
|
# ifdef ENABLE_HTTP3
|
||||||
if ((!apiconf.enabled || i != 0) &&
|
if ((!apiconf.enabled || i != 0) &&
|
||||||
worker->setup_quic_server_socket() != 0) {
|
worker->setup_quic_server_socket() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
# endif // ENABLE_HTTP3
|
||||||
|
|
||||||
workers_.push_back(std::move(worker));
|
workers_.push_back(std::move(worker));
|
||||||
worker_loops_.push_back(loop);
|
worker_loops_.push_back(loop);
|
||||||
|
@ -646,7 +670,9 @@ void ConnectionHandler::handle_ocsp_complete() {
|
||||||
ev_child_stop(loop_, &ocsp_.chldev);
|
ev_child_stop(loop_, &ocsp_.chldev);
|
||||||
|
|
||||||
assert(ocsp_.next < all_ssl_ctx_.size());
|
assert(ocsp_.next < all_ssl_ctx_.size());
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
assert(all_ssl_ctx_.size() == quic_all_ssl_ctx_.size());
|
assert(all_ssl_ctx_.size() == quic_all_ssl_ctx_.size());
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
auto ssl_ctx = all_ssl_ctx_[ocsp_.next];
|
auto ssl_ctx = all_ssl_ctx_[ocsp_.next];
|
||||||
auto tls_ctx_data =
|
auto tls_ctx_data =
|
||||||
|
@ -674,6 +700,7 @@ void ConnectionHandler::handle_ocsp_complete() {
|
||||||
if (tlsconf.ocsp.no_verify ||
|
if (tlsconf.ocsp.no_verify ||
|
||||||
tls::verify_ocsp_response(ssl_ctx, ocsp_.resp.data(),
|
tls::verify_ocsp_response(ssl_ctx, ocsp_.resp.data(),
|
||||||
ocsp_.resp.size()) == 0) {
|
ocsp_.resp.size()) == 0) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
// We have list of SSL_CTX with the same certificate in
|
// We have list of SSL_CTX with the same certificate in
|
||||||
// quic_all_ssl_ctx_ as well. Some SSL_CTXs are missing there in
|
// quic_all_ssl_ctx_ as well. Some SSL_CTXs are missing there in
|
||||||
// that case we get nullptr.
|
// that case we get nullptr.
|
||||||
|
@ -681,7 +708,7 @@ void ConnectionHandler::handle_ocsp_complete() {
|
||||||
if (quic_ssl_ctx) {
|
if (quic_ssl_ctx) {
|
||||||
auto quic_tls_ctx_data = static_cast<tls::TLSContextData *>(
|
auto quic_tls_ctx_data = static_cast<tls::TLSContextData *>(
|
||||||
SSL_CTX_get_app_data(quic_ssl_ctx));
|
SSL_CTX_get_app_data(quic_ssl_ctx));
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
# ifndef OPENSSL_IS_BORINGSSL
|
||||||
# ifdef HAVE_ATOMIC_STD_SHARED_PTR
|
# ifdef HAVE_ATOMIC_STD_SHARED_PTR
|
||||||
std::atomic_store_explicit(
|
std::atomic_store_explicit(
|
||||||
&quic_tls_ctx_data->ocsp_data,
|
&quic_tls_ctx_data->ocsp_data,
|
||||||
|
@ -692,10 +719,11 @@ void ConnectionHandler::handle_ocsp_complete() {
|
||||||
quic_tls_ctx_data->ocsp_data =
|
quic_tls_ctx_data->ocsp_data =
|
||||||
std::make_shared<std::vector<uint8_t>>(ocsp_.resp);
|
std::make_shared<std::vector<uint8_t>>(ocsp_.resp);
|
||||||
# endif // !HAVE_ATOMIC_STD_SHARED_PTR
|
# endif // !HAVE_ATOMIC_STD_SHARED_PTR
|
||||||
#else // OPENSSL_IS_BORINGSSL
|
# else // OPENSSL_IS_BORINGSSL
|
||||||
SSL_CTX_set_ocsp_response(ssl_ctx, ocsp_.resp.data(), ocsp_.resp.size());
|
SSL_CTX_set_ocsp_response(ssl_ctx, ocsp_.resp.data(), ocsp_.resp.size());
|
||||||
#endif // OPENSSL_IS_BORINGSSL
|
# endif // OPENSSL_IS_BORINGSSL
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
# ifdef HAVE_ATOMIC_STD_SHARED_PTR
|
# ifdef HAVE_ATOMIC_STD_SHARED_PTR
|
||||||
|
@ -877,7 +905,9 @@ SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() {
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
all_ssl_ctx_.push_back(ssl_ctx);
|
all_ssl_ctx_.push_back(ssl_ctx);
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic_all_ssl_ctx_.push_back(nullptr);
|
quic_all_ssl_ctx_.push_back(nullptr);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
@ -940,10 +970,12 @@ ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const {
|
||||||
return indexed_ssl_ctx_[idx];
|
return indexed_ssl_ctx_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
const std::vector<SSL_CTX *> &
|
const std::vector<SSL_CTX *> &
|
||||||
ConnectionHandler::get_quic_indexed_ssl_ctx(size_t idx) const {
|
ConnectionHandler::get_quic_indexed_ssl_ctx(size_t idx) const {
|
||||||
return quic_indexed_ssl_ctx_[idx];
|
return quic_indexed_ssl_ctx_[idx];
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
void ConnectionHandler::set_enable_acceptor_on_ocsp_completion(bool f) {
|
void ConnectionHandler::set_enable_acceptor_on_ocsp_completion(bool f) {
|
||||||
enable_acceptor_on_ocsp_completion_ = f;
|
enable_acceptor_on_ocsp_completion_ = f;
|
||||||
|
|
|
@ -159,7 +159,9 @@ public:
|
||||||
SSL_CTX *get_ssl_ctx(size_t idx) const;
|
SSL_CTX *get_ssl_ctx(size_t idx) const;
|
||||||
|
|
||||||
const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const;
|
const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
const std::vector<SSL_CTX *> &get_quic_indexed_ssl_ctx(size_t idx) const;
|
const std::vector<SSL_CTX *> &get_quic_indexed_ssl_ctx(size_t idx) const;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#ifdef HAVE_NEVERBLEED
|
#ifdef HAVE_NEVERBLEED
|
||||||
void set_neverbleed(neverbleed_t *nb);
|
void set_neverbleed(neverbleed_t *nb);
|
||||||
|
@ -188,8 +190,10 @@ private:
|
||||||
// selection among them are performed by hostname presented by SNI,
|
// selection among them are performed by hostname presented by SNI,
|
||||||
// and signature algorithm presented by client.
|
// and signature algorithm presented by client.
|
||||||
std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_;
|
std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
std::vector<SSL_CTX *> quic_all_ssl_ctx_;
|
std::vector<SSL_CTX *> quic_all_ssl_ctx_;
|
||||||
std::vector<std::vector<SSL_CTX *>> quic_indexed_ssl_ctx_;
|
std::vector<std::vector<SSL_CTX *>> quic_indexed_ssl_ctx_;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
OCSPUpdateContext ocsp_;
|
OCSPUpdateContext ocsp_;
|
||||||
std::mt19937 &gen_;
|
std::mt19937 &gen_;
|
||||||
// ev_loop for each worker
|
// ev_loop for each worker
|
||||||
|
@ -206,7 +210,9 @@ private:
|
||||||
// Otherwise, nullptr and workers_ has instances of Worker instead.
|
// Otherwise, nullptr and workers_ has instances of Worker instead.
|
||||||
std::unique_ptr<Worker> single_worker_;
|
std::unique_ptr<Worker> single_worker_;
|
||||||
std::unique_ptr<tls::CertLookupTree> cert_tree_;
|
std::unique_ptr<tls::CertLookupTree> cert_tree_;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
std::unique_ptr<tls::CertLookupTree> quic_cert_tree_;
|
std::unique_ptr<tls::CertLookupTree> quic_cert_tree_;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_;
|
std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_;
|
||||||
// Current TLS session ticket keys. Note that TLS connection does
|
// Current TLS session ticket keys. Note that TLS connection does
|
||||||
// not refer to this field directly. They use TicketKeys object in
|
// not refer to this field directly. They use TicketKeys object in
|
||||||
|
|
|
@ -165,7 +165,9 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
|
||||||
downstream_wtimer_.data = this;
|
downstream_wtimer_.data = this;
|
||||||
|
|
||||||
rcbufs_.reserve(32);
|
rcbufs_.reserve(32);
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
rcbufs3_.reserve(32);
|
rcbufs3_.reserve(32);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
}
|
}
|
||||||
|
|
||||||
Downstream::~Downstream() {
|
Downstream::~Downstream() {
|
||||||
|
@ -205,9 +207,11 @@ Downstream::~Downstream() {
|
||||||
// explicitly.
|
// explicitly.
|
||||||
dconn_.reset();
|
dconn_.reset();
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
for (auto rcbuf : rcbufs3_) {
|
for (auto rcbuf : rcbufs3_) {
|
||||||
nghttp3_rcbuf_decref(rcbuf);
|
nghttp3_rcbuf_decref(rcbuf);
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
for (auto rcbuf : rcbufs_) {
|
for (auto rcbuf : rcbufs_) {
|
||||||
nghttp2_rcbuf_decref(rcbuf);
|
nghttp2_rcbuf_decref(rcbuf);
|
||||||
|
@ -1134,10 +1138,12 @@ void Downstream::add_rcbuf(nghttp2_rcbuf *rcbuf) {
|
||||||
rcbufs_.push_back(rcbuf);
|
rcbufs_.push_back(rcbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
void Downstream::add_rcbuf(nghttp3_rcbuf *rcbuf) {
|
void Downstream::add_rcbuf(nghttp3_rcbuf *rcbuf) {
|
||||||
nghttp3_rcbuf_incref(rcbuf);
|
nghttp3_rcbuf_incref(rcbuf);
|
||||||
rcbufs3_.push_back(rcbuf);
|
rcbufs3_.push_back(rcbuf);
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
void Downstream::set_downstream_addr_group(
|
void Downstream::set_downstream_addr_group(
|
||||||
const std::shared_ptr<DownstreamAddrGroup> &group) {
|
const std::shared_ptr<DownstreamAddrGroup> &group) {
|
||||||
|
|
|
@ -38,7 +38,9 @@
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#include <nghttp3/nghttp3.h>
|
#ifdef ENABLE_HTTP3
|
||||||
|
# include <nghttp3/nghttp3.h>
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#include "llhttp.h"
|
#include "llhttp.h"
|
||||||
|
|
||||||
|
@ -490,7 +492,9 @@ public:
|
||||||
BlockAllocator &get_block_allocator();
|
BlockAllocator &get_block_allocator();
|
||||||
|
|
||||||
void add_rcbuf(nghttp2_rcbuf *rcbuf);
|
void add_rcbuf(nghttp2_rcbuf *rcbuf);
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
void add_rcbuf(nghttp3_rcbuf *rcbuf);
|
void add_rcbuf(nghttp3_rcbuf *rcbuf);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
void
|
void
|
||||||
set_downstream_addr_group(const std::shared_ptr<DownstreamAddrGroup> &group);
|
set_downstream_addr_group(const std::shared_ptr<DownstreamAddrGroup> &group);
|
||||||
|
@ -533,7 +537,9 @@ private:
|
||||||
BlockAllocator balloc_;
|
BlockAllocator balloc_;
|
||||||
|
|
||||||
std::vector<nghttp2_rcbuf *> rcbufs_;
|
std::vector<nghttp2_rcbuf *> rcbufs_;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
std::vector<nghttp3_rcbuf *> rcbufs3_;
|
std::vector<nghttp3_rcbuf *> rcbufs3_;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
Request req_;
|
Request req_;
|
||||||
Response resp_;
|
Response resp_;
|
||||||
|
|
|
@ -51,9 +51,11 @@
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#include <ngtcp2/ngtcp2.h>
|
#ifdef ENABLE_HTTP3
|
||||||
#include <ngtcp2/ngtcp2_crypto.h>
|
# include <ngtcp2/ngtcp2.h>
|
||||||
#include <ngtcp2/ngtcp2_crypto_openssl.h>
|
# include <ngtcp2/ngtcp2_crypto.h>
|
||||||
|
# include <ngtcp2/ngtcp2_crypto_openssl.h>
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#include "shrpx_log.h"
|
#include "shrpx_log.h"
|
||||||
#include "shrpx_client_handler.h"
|
#include "shrpx_client_handler.h"
|
||||||
|
@ -64,7 +66,9 @@
|
||||||
#include "shrpx_memcached_request.h"
|
#include "shrpx_memcached_request.h"
|
||||||
#include "shrpx_memcached_dispatcher.h"
|
#include "shrpx_memcached_dispatcher.h"
|
||||||
#include "shrpx_connection_handler.h"
|
#include "shrpx_connection_handler.h"
|
||||||
#include "shrpx_http3_upstream.h"
|
#ifdef ENABLE_HTTP3
|
||||||
|
# include "shrpx_http3_upstream.h"
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
@ -185,8 +189,12 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
|
||||||
|
|
||||||
auto hostname = StringRef{std::begin(buf), end_buf};
|
auto hostname = StringRef{std::begin(buf), end_buf};
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
auto cert_tree = SSL_is_quic(ssl) ? worker->get_quic_cert_lookup_tree()
|
auto cert_tree = SSL_is_quic(ssl) ? worker->get_quic_cert_lookup_tree()
|
||||||
: worker->get_cert_lookup_tree();
|
: worker->get_cert_lookup_tree();
|
||||||
|
#else // !ENABLE_HTTP3
|
||||||
|
auto cert_tree = worker->get_cert_lookup_tree();
|
||||||
|
#endif // !ENABLE_HTTP3
|
||||||
|
|
||||||
auto idx = cert_tree->lookup(hostname);
|
auto idx = cert_tree->lookup(hostname);
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
|
@ -197,9 +205,14 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
|
||||||
|
|
||||||
auto conn_handler = worker->get_connection_handler();
|
auto conn_handler = worker->get_connection_handler();
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
const auto &ssl_ctx_list = SSL_is_quic(ssl)
|
const auto &ssl_ctx_list = SSL_is_quic(ssl)
|
||||||
? conn_handler->get_quic_indexed_ssl_ctx(idx)
|
? conn_handler->get_quic_indexed_ssl_ctx(idx)
|
||||||
: conn_handler->get_indexed_ssl_ctx(idx);
|
: conn_handler->get_indexed_ssl_ctx(idx);
|
||||||
|
#else // !ENABLE_HTTP3
|
||||||
|
const auto &ssl_ctx_list = conn_handler->get_indexed_ssl_ctx(idx);
|
||||||
|
#endif // !ENABLE_HTTP3
|
||||||
|
|
||||||
assert(!ssl_ctx_list.empty());
|
assert(!ssl_ctx_list.empty());
|
||||||
|
|
||||||
#if !defined(OPENSSL_IS_BORINGSSL) && !LIBRESSL_IN_USE && \
|
#if !defined(OPENSSL_IS_BORINGSSL) && !LIBRESSL_IN_USE && \
|
||||||
|
@ -608,7 +621,8 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||||
} // namespace
|
} // namespace
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#ifdef ENABLE_HTTP3
|
||||||
|
# if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
namespace {
|
namespace {
|
||||||
int quic_alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
int quic_alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||||
unsigned char *outlen, const unsigned char *in,
|
unsigned char *outlen, const unsigned char *in,
|
||||||
|
@ -632,7 +646,8 @@ int quic_alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
# endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
@ -1076,6 +1091,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
namespace {
|
namespace {
|
||||||
int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
|
int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
|
||||||
const uint8_t *rx_secret,
|
const uint8_t *rx_secret,
|
||||||
|
@ -1143,10 +1159,10 @@ auto quic_method = SSL_QUIC_METHOD{
|
||||||
SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
const char *cert_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
|
||||||
,
|
,
|
||||||
neverbleed_t *nb
|
neverbleed_t *nb
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
) {
|
) {
|
||||||
auto ssl_ctx = SSL_CTX_new(TLS_server_method());
|
auto ssl_ctx = SSL_CTX_new(TLS_server_method());
|
||||||
if (!ssl_ctx) {
|
if (!ssl_ctx) {
|
||||||
|
@ -1159,14 +1175,14 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
|
||||||
SSL_OP_SINGLE_DH_USE |
|
SSL_OP_SINGLE_DH_USE |
|
||||||
SSL_OP_CIPHER_SERVER_PREFERENCE
|
SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||||
#if OPENSSL_1_1_1_API
|
# if OPENSSL_1_1_1_API
|
||||||
// The reason for disabling built-in anti-replay in OpenSSL is
|
// The reason for disabling built-in anti-replay in OpenSSL is
|
||||||
// that it only works if client gets back to the same server.
|
// that it only works if client gets back to the same server.
|
||||||
// The freshness check described in
|
// The freshness check described in
|
||||||
// https://tools.ietf.org/html/rfc8446#section-8.3 is still
|
// https://tools.ietf.org/html/rfc8446#section-8.3 is still
|
||||||
// performed.
|
// performed.
|
||||||
| SSL_OP_NO_ANTI_REPLAY
|
| SSL_OP_NO_ANTI_REPLAY
|
||||||
#endif // OPENSSL_1_1_1_API
|
# endif // OPENSSL_1_1_1_API
|
||||||
;
|
;
|
||||||
|
|
||||||
auto config = mod_config();
|
auto config = mod_config();
|
||||||
|
@ -1194,15 +1210,15 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
DIE();
|
DIE();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENSSL_1_1_1_API
|
# if OPENSSL_1_1_1_API
|
||||||
if (SSL_CTX_set_ciphersuites(ssl_ctx, tlsconf.tls13_ciphers.c_str()) == 0) {
|
if (SSL_CTX_set_ciphersuites(ssl_ctx, tlsconf.tls13_ciphers.c_str()) == 0) {
|
||||||
LOG(FATAL) << "SSL_CTX_set_ciphersuites " << tlsconf.tls13_ciphers
|
LOG(FATAL) << "SSL_CTX_set_ciphersuites " << tlsconf.tls13_ciphers
|
||||||
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr);
|
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr);
|
||||||
DIE();
|
DIE();
|
||||||
}
|
}
|
||||||
#endif // OPENSSL_1_1_1_API
|
# endif // OPENSSL_1_1_1_API
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_EC
|
# ifndef OPENSSL_NO_EC
|
||||||
# if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
# if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
if (SSL_CTX_set1_curves_list(ssl_ctx, tlsconf.ecdh_curves.c_str()) != 1) {
|
if (SSL_CTX_set1_curves_list(ssl_ctx, tlsconf.ecdh_curves.c_str()) != 1) {
|
||||||
LOG(FATAL) << "SSL_CTX_set1_curves_list " << tlsconf.ecdh_curves
|
LOG(FATAL) << "SSL_CTX_set1_curves_list " << tlsconf.ecdh_curves
|
||||||
|
@ -1226,7 +1242,7 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
|
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
|
||||||
EC_KEY_free(ecdh);
|
EC_KEY_free(ecdh);
|
||||||
# endif // LIBRESSL_LEGACY_API || OPENSSL_VERSION_NUBMER < 0x10002000L
|
# endif // LIBRESSL_LEGACY_API || OPENSSL_VERSION_NUBMER < 0x10002000L
|
||||||
#endif // OPENSSL_NO_EC
|
# endif // OPENSSL_NO_EC
|
||||||
|
|
||||||
if (!tlsconf.dh_param_file.empty()) {
|
if (!tlsconf.dh_param_file.empty()) {
|
||||||
// Read DH parameters from file
|
// Read DH parameters from file
|
||||||
|
@ -1269,20 +1285,20 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, config);
|
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_NEVERBLEED
|
# ifndef HAVE_NEVERBLEED
|
||||||
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key_file,
|
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key_file,
|
||||||
SSL_FILETYPE_PEM) != 1) {
|
SSL_FILETYPE_PEM) != 1) {
|
||||||
LOG(FATAL) << "SSL_CTX_use_PrivateKey_file failed: "
|
LOG(FATAL) << "SSL_CTX_use_PrivateKey_file failed: "
|
||||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||||
}
|
}
|
||||||
#else // HAVE_NEVERBLEED
|
# else // HAVE_NEVERBLEED
|
||||||
std::array<char, NEVERBLEED_ERRBUF_SIZE> errbuf;
|
std::array<char, NEVERBLEED_ERRBUF_SIZE> errbuf;
|
||||||
if (neverbleed_load_private_key_file(nb, ssl_ctx, private_key_file,
|
if (neverbleed_load_private_key_file(nb, ssl_ctx, private_key_file,
|
||||||
errbuf.data()) != 1) {
|
errbuf.data()) != 1) {
|
||||||
LOG(FATAL) << "neverbleed_load_private_key_file failed: " << errbuf.data();
|
LOG(FATAL) << "neverbleed_load_private_key_file failed: " << errbuf.data();
|
||||||
DIE();
|
DIE();
|
||||||
}
|
}
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
|
|
||||||
if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file) != 1) {
|
if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file) != 1) {
|
||||||
LOG(FATAL) << "SSL_CTX_use_certificate_file failed: "
|
LOG(FATAL) << "SSL_CTX_use_certificate_file failed: "
|
||||||
|
@ -1324,20 +1340,20 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
}
|
}
|
||||||
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
|
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, servername_callback);
|
||||||
SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx, ticket_key_cb);
|
SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx, ticket_key_cb);
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
# ifndef OPENSSL_IS_BORINGSSL
|
||||||
SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
|
SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
|
||||||
#endif // OPENSSL_IS_BORINGSSL
|
# endif // OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
# ifdef OPENSSL_IS_BORINGSSL
|
||||||
SSL_CTX_set_early_data_enabled(ssl_ctx, 1);
|
SSL_CTX_set_early_data_enabled(ssl_ctx, 1);
|
||||||
#endif // OPENSSL_IS_BORINGSSL
|
# endif // OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
# if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
// ALPN selection callback
|
// ALPN selection callback
|
||||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, quic_alpn_select_proto_cb, nullptr);
|
SSL_CTX_set_alpn_select_cb(ssl_ctx, quic_alpn_select_proto_cb, nullptr);
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
# endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L && \
|
# if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L && \
|
||||||
!defined(OPENSSL_IS_BORINGSSL)
|
!defined(OPENSSL_IS_BORINGSSL)
|
||||||
// SSL_extension_supported(TLSEXT_TYPE_signed_certificate_timestamp)
|
// SSL_extension_supported(TLSEXT_TYPE_signed_certificate_timestamp)
|
||||||
// returns 1, which means OpenSSL internally handles it. But
|
// returns 1, which means OpenSSL internally handles it. But
|
||||||
|
@ -1369,21 +1385,21 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
}
|
}
|
||||||
# endif // !OPENSSL_1_1_1_API
|
# endif // !OPENSSL_1_1_1_API
|
||||||
}
|
}
|
||||||
#endif // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&
|
# endif // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L &&
|
||||||
// !defined(OPENSSL_IS_BORINGSSL)
|
// !defined(OPENSSL_IS_BORINGSSL)
|
||||||
|
|
||||||
#if OPENSSL_1_1_1_API
|
# if OPENSSL_1_1_1_API
|
||||||
if (SSL_CTX_set_max_early_data(ssl_ctx,
|
if (SSL_CTX_set_max_early_data(ssl_ctx,
|
||||||
std::numeric_limits<uint32_t>::max()) != 1) {
|
std::numeric_limits<uint32_t>::max()) != 1) {
|
||||||
LOG(FATAL) << "SSL_CTX_set_max_early_data failed: "
|
LOG(FATAL) << "SSL_CTX_set_max_early_data failed: "
|
||||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||||
DIE();
|
DIE();
|
||||||
}
|
}
|
||||||
#endif // OPENSSL_1_1_1_API
|
# endif // OPENSSL_1_1_1_API
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_PSK
|
# ifndef OPENSSL_NO_PSK
|
||||||
SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
|
SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
|
||||||
#endif // !LIBRESSL_NO_PSK
|
# endif // !LIBRESSL_NO_PSK
|
||||||
|
|
||||||
SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
|
SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
|
||||||
|
|
||||||
|
@ -1395,6 +1411,7 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int select_h2_next_proto_cb(SSL *ssl, unsigned char **out,
|
int select_h2_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||||
|
@ -2101,9 +2118,11 @@ bool in_proto_list(const std::vector<StringRef> &protos,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool upstream_tls_enabled(const ConnectionConfig &connconf) {
|
bool upstream_tls_enabled(const ConnectionConfig &connconf) {
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
if (connconf.quic_listener.addrs.size()) {
|
if (connconf.quic_listener.addrs.size()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
const auto &faddrs = connconf.listener.addrs;
|
const auto &faddrs = connconf.listener.addrs;
|
||||||
return std::any_of(std::begin(faddrs), std::end(faddrs),
|
return std::any_of(std::begin(faddrs), std::end(faddrs),
|
||||||
|
@ -2184,14 +2203,15 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX *setup_quic_server_ssl_context(
|
SSL_CTX *setup_quic_server_ssl_context(
|
||||||
std::vector<SSL_CTX *> &all_ssl_ctx,
|
std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||||
std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
|
std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
|
||||||
CertLookupTree *cert_tree
|
CertLookupTree *cert_tree
|
||||||
#ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
,
|
,
|
||||||
neverbleed_t *nb
|
neverbleed_t *nb
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
) {
|
) {
|
||||||
auto config = get_config();
|
auto config = get_config();
|
||||||
|
|
||||||
|
@ -2204,10 +2224,10 @@ SSL_CTX *setup_quic_server_ssl_context(
|
||||||
auto ssl_ctx =
|
auto ssl_ctx =
|
||||||
create_quic_ssl_context(tlsconf.private_key_file.c_str(),
|
create_quic_ssl_context(tlsconf.private_key_file.c_str(),
|
||||||
tlsconf.cert_file.c_str(), tlsconf.sct_data
|
tlsconf.cert_file.c_str(), tlsconf.sct_data
|
||||||
#ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
,
|
,
|
||||||
nb
|
nb
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
|
||||||
all_ssl_ctx.push_back(ssl_ctx);
|
all_ssl_ctx.push_back(ssl_ctx);
|
||||||
|
@ -2222,10 +2242,10 @@ SSL_CTX *setup_quic_server_ssl_context(
|
||||||
for (auto &c : tlsconf.subcerts) {
|
for (auto &c : tlsconf.subcerts) {
|
||||||
auto ssl_ctx = create_quic_ssl_context(c.private_key_file.c_str(),
|
auto ssl_ctx = create_quic_ssl_context(c.private_key_file.c_str(),
|
||||||
c.cert_file.c_str(), c.sct_data
|
c.cert_file.c_str(), c.sct_data
|
||||||
#ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
,
|
,
|
||||||
nb
|
nb
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
all_ssl_ctx.push_back(ssl_ctx);
|
all_ssl_ctx.push_back(ssl_ctx);
|
||||||
|
|
||||||
|
@ -2238,6 +2258,7 @@ SSL_CTX *setup_quic_server_ssl_context(
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
SSL_CTX *setup_downstream_client_ssl_context(
|
SSL_CTX *setup_downstream_client_ssl_context(
|
||||||
#ifdef HAVE_NEVERBLEED
|
#ifdef HAVE_NEVERBLEED
|
||||||
|
|
|
@ -100,15 +100,17 @@ SSL_CTX *create_ssl_client_context(
|
||||||
unsigned char *outlen, const unsigned char *in,
|
unsigned char *outlen, const unsigned char *in,
|
||||||
unsigned int inlen, void *arg));
|
unsigned int inlen, void *arg));
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX *create_quic_ssl_client_context(
|
SSL_CTX *create_quic_ssl_client_context(
|
||||||
#ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
neverbleed_t *nb,
|
neverbleed_t *nb,
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
const StringRef &cacert, const StringRef &cert_file,
|
const StringRef &cacert, const StringRef &cert_file,
|
||||||
const StringRef &private_key_file,
|
const StringRef &private_key_file,
|
||||||
int (*next_proto_select_cb)(SSL *s, unsigned char **out,
|
int (*next_proto_select_cb)(SSL *s, unsigned char **out,
|
||||||
unsigned char *outlen, const unsigned char *in,
|
unsigned char *outlen, const unsigned char *in,
|
||||||
unsigned int inlen, void *arg));
|
unsigned int inlen, void *arg));
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
ClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr,
|
ClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr,
|
||||||
int addrlen, const UpstreamAddr *faddr);
|
int addrlen, const UpstreamAddr *faddr);
|
||||||
|
@ -227,15 +229,17 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||||
#endif // HAVE_NEVERBLEED
|
#endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX *setup_quic_server_ssl_context(
|
SSL_CTX *setup_quic_server_ssl_context(
|
||||||
std::vector<SSL_CTX *> &all_ssl_ctx,
|
std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||||
std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
|
std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
|
||||||
CertLookupTree *cert_tree
|
CertLookupTree *cert_tree
|
||||||
#ifdef HAVE_NEVERBLEED
|
# ifdef HAVE_NEVERBLEED
|
||||||
,
|
,
|
||||||
neverbleed_t *nb
|
neverbleed_t *nb
|
||||||
#endif // HAVE_NEVERBLEED
|
# endif // HAVE_NEVERBLEED
|
||||||
);
|
);
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
// Setups client side SSL_CTX.
|
// Setups client side SSL_CTX.
|
||||||
SSL_CTX *setup_downstream_client_ssl_context(
|
SSL_CTX *setup_downstream_client_ssl_context(
|
||||||
|
|
|
@ -39,8 +39,10 @@
|
||||||
#ifdef HAVE_MRUBY
|
#ifdef HAVE_MRUBY
|
||||||
# include "shrpx_mruby.h"
|
# include "shrpx_mruby.h"
|
||||||
#endif // HAVE_MRUBY
|
#endif // HAVE_MRUBY
|
||||||
#include "shrpx_quic.h"
|
#ifdef ENABLE_HTTP3
|
||||||
#include "shrpx_quic_listener.h"
|
# include "shrpx_quic.h"
|
||||||
|
# include "shrpx_quic_listener.h"
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
|
||||||
|
@ -132,23 +134,29 @@ create_downstream_key(const std::shared_ptr<SharedDownstreamAddr> &shared_addr,
|
||||||
|
|
||||||
Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
||||||
SSL_CTX *tls_session_cache_memcached_ssl_ctx,
|
SSL_CTX *tls_session_cache_memcached_ssl_ctx,
|
||||||
tls::CertLookupTree *cert_tree, SSL_CTX *quic_sv_ssl_ctx,
|
tls::CertLookupTree *cert_tree,
|
||||||
tls::CertLookupTree *quic_cert_tree,
|
#ifdef ENABLE_HTTP3
|
||||||
|
SSL_CTX *quic_sv_ssl_ctx, tls::CertLookupTree *quic_cert_tree,
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
const std::shared_ptr<TicketKeys> &ticket_keys,
|
const std::shared_ptr<TicketKeys> &ticket_keys,
|
||||||
ConnectionHandler *conn_handler,
|
ConnectionHandler *conn_handler,
|
||||||
std::shared_ptr<DownstreamConfig> downstreamconf)
|
std::shared_ptr<DownstreamConfig> downstreamconf)
|
||||||
: randgen_(util::make_mt19937()),
|
: randgen_(util::make_mt19937()),
|
||||||
worker_stat_{},
|
worker_stat_{},
|
||||||
dns_tracker_(loop),
|
dns_tracker_(loop),
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic_upstream_addrs_{get_config()->conn.quic_listener.addrs},
|
quic_upstream_addrs_{get_config()->conn.quic_listener.addrs},
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
loop_(loop),
|
loop_(loop),
|
||||||
sv_ssl_ctx_(sv_ssl_ctx),
|
sv_ssl_ctx_(sv_ssl_ctx),
|
||||||
cl_ssl_ctx_(cl_ssl_ctx),
|
cl_ssl_ctx_(cl_ssl_ctx),
|
||||||
cert_tree_(cert_tree),
|
cert_tree_(cert_tree),
|
||||||
conn_handler_(conn_handler),
|
conn_handler_(conn_handler),
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
quic_sv_ssl_ctx_{quic_sv_ssl_ctx},
|
quic_sv_ssl_ctx_{quic_sv_ssl_ctx},
|
||||||
quic_cert_tree_{quic_cert_tree},
|
quic_cert_tree_{quic_cert_tree},
|
||||||
quic_conn_handler_{this},
|
quic_conn_handler_{this},
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
ticket_keys_(ticket_keys),
|
ticket_keys_(ticket_keys),
|
||||||
connect_blocker_(
|
connect_blocker_(
|
||||||
std::make_unique<ConnectBlocker>(randgen_, loop_, nullptr, nullptr)),
|
std::make_unique<ConnectBlocker>(randgen_, loop_, nullptr, nullptr)),
|
||||||
|
@ -511,9 +519,11 @@ void Worker::process_events() {
|
||||||
|
|
||||||
tls::CertLookupTree *Worker::get_cert_lookup_tree() const { return cert_tree_; }
|
tls::CertLookupTree *Worker::get_cert_lookup_tree() const { return cert_tree_; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
tls::CertLookupTree *Worker::get_quic_cert_lookup_tree() const {
|
tls::CertLookupTree *Worker::get_quic_cert_lookup_tree() const {
|
||||||
return quic_cert_tree_;
|
return quic_cert_tree_;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
std::shared_ptr<TicketKeys> Worker::get_ticket_keys() {
|
std::shared_ptr<TicketKeys> Worker::get_ticket_keys() {
|
||||||
#ifdef HAVE_ATOMIC_STD_SHARED_PTR
|
#ifdef HAVE_ATOMIC_STD_SHARED_PTR
|
||||||
|
@ -545,7 +555,9 @@ SSL_CTX *Worker::get_sv_ssl_ctx() const { return sv_ssl_ctx_; }
|
||||||
|
|
||||||
SSL_CTX *Worker::get_cl_ssl_ctx() const { return cl_ssl_ctx_; }
|
SSL_CTX *Worker::get_cl_ssl_ctx() const { return cl_ssl_ctx_; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX *Worker::get_quic_sv_ssl_ctx() const { return quic_sv_ssl_ctx_; }
|
SSL_CTX *Worker::get_quic_sv_ssl_ctx() const { return quic_sv_ssl_ctx_; }
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
void Worker::set_graceful_shutdown(bool f) { graceful_shutdown_ = f; }
|
void Worker::set_graceful_shutdown(bool f) { graceful_shutdown_ = f; }
|
||||||
|
|
||||||
|
@ -591,12 +603,15 @@ ConnectionHandler *Worker::get_connection_handler() const {
|
||||||
return conn_handler_;
|
return conn_handler_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
QUICConnectionHandler *Worker::get_quic_connection_handler() {
|
QUICConnectionHandler *Worker::get_quic_connection_handler() {
|
||||||
return &quic_conn_handler_;
|
return &quic_conn_handler_;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
DNSTracker *Worker::get_dns_tracker() { return &dns_tracker_; }
|
DNSTracker *Worker::get_dns_tracker() { return &dns_tracker_; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
int Worker::setup_quic_server_socket() {
|
int Worker::setup_quic_server_socket() {
|
||||||
for (auto &addr : quic_upstream_addrs_) {
|
for (auto &addr : quic_upstream_addrs_) {
|
||||||
assert(!addr.host_unix);
|
assert(!addr.host_unix);
|
||||||
|
@ -609,6 +624,7 @@ int Worker::setup_quic_server_socket() {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
size_t match_downstream_addr_group_host(
|
size_t match_downstream_addr_group_host(
|
||||||
|
|
|
@ -50,7 +50,9 @@
|
||||||
#include "shrpx_live_check.h"
|
#include "shrpx_live_check.h"
|
||||||
#include "shrpx_connect_blocker.h"
|
#include "shrpx_connect_blocker.h"
|
||||||
#include "shrpx_dns_tracker.h"
|
#include "shrpx_dns_tracker.h"
|
||||||
#include "shrpx_quic_connection_handler.h"
|
#ifdef ENABLE_HTTP3
|
||||||
|
# include "shrpx_quic_connection_handler.h"
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
#include "allocator.h"
|
#include "allocator.h"
|
||||||
|
|
||||||
using namespace nghttp2;
|
using namespace nghttp2;
|
||||||
|
@ -62,7 +64,9 @@ class ConnectBlocker;
|
||||||
class MemcachedDispatcher;
|
class MemcachedDispatcher;
|
||||||
struct UpstreamAddr;
|
struct UpstreamAddr;
|
||||||
class ConnectionHandler;
|
class ConnectionHandler;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
class QUICListener;
|
class QUICListener;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#ifdef HAVE_MRUBY
|
#ifdef HAVE_MRUBY
|
||||||
namespace mruby {
|
namespace mruby {
|
||||||
|
@ -271,8 +275,10 @@ class Worker {
|
||||||
public:
|
public:
|
||||||
Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
||||||
SSL_CTX *tls_session_cache_memcached_ssl_ctx,
|
SSL_CTX *tls_session_cache_memcached_ssl_ctx,
|
||||||
tls::CertLookupTree *cert_tree, SSL_CTX *quic_sv_ssl_ctx,
|
tls::CertLookupTree *cert_tree,
|
||||||
tls::CertLookupTree *quic_cert_tree,
|
#ifdef ENABLE_HTTP3
|
||||||
|
SSL_CTX *quic_sv_ssl_ctx, tls::CertLookupTree *quic_cert_tree,
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
const std::shared_ptr<TicketKeys> &ticket_keys,
|
const std::shared_ptr<TicketKeys> &ticket_keys,
|
||||||
ConnectionHandler *conn_handler,
|
ConnectionHandler *conn_handler,
|
||||||
std::shared_ptr<DownstreamConfig> downstreamconf);
|
std::shared_ptr<DownstreamConfig> downstreamconf);
|
||||||
|
@ -283,7 +289,9 @@ public:
|
||||||
void send(const WorkerEvent &event);
|
void send(const WorkerEvent &event);
|
||||||
|
|
||||||
tls::CertLookupTree *get_cert_lookup_tree() const;
|
tls::CertLookupTree *get_cert_lookup_tree() const;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
tls::CertLookupTree *get_quic_cert_lookup_tree() const;
|
tls::CertLookupTree *get_quic_cert_lookup_tree() const;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
// These 2 functions make a lock m_ to get/set ticket keys
|
// These 2 functions make a lock m_ to get/set ticket keys
|
||||||
// atomically.
|
// atomically.
|
||||||
|
@ -294,7 +302,9 @@ public:
|
||||||
struct ev_loop *get_loop() const;
|
struct ev_loop *get_loop() const;
|
||||||
SSL_CTX *get_sv_ssl_ctx() const;
|
SSL_CTX *get_sv_ssl_ctx() const;
|
||||||
SSL_CTX *get_cl_ssl_ctx() const;
|
SSL_CTX *get_cl_ssl_ctx() const;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX *get_quic_sv_ssl_ctx() const;
|
SSL_CTX *get_quic_sv_ssl_ctx() const;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
void set_graceful_shutdown(bool f);
|
void set_graceful_shutdown(bool f);
|
||||||
bool get_graceful_shutdown() const;
|
bool get_graceful_shutdown() const;
|
||||||
|
@ -324,11 +334,13 @@ public:
|
||||||
|
|
||||||
ConnectionHandler *get_connection_handler() const;
|
ConnectionHandler *get_connection_handler() const;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
QUICConnectionHandler *get_quic_connection_handler();
|
QUICConnectionHandler *get_quic_connection_handler();
|
||||||
|
|
||||||
DNSTracker *get_dns_tracker();
|
|
||||||
|
|
||||||
int setup_quic_server_socket();
|
int setup_quic_server_socket();
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
|
DNSTracker *get_dns_tracker();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifndef NOTHREADS
|
#ifndef NOTHREADS
|
||||||
|
@ -344,8 +356,10 @@ private:
|
||||||
WorkerStat worker_stat_;
|
WorkerStat worker_stat_;
|
||||||
DNSTracker dns_tracker_;
|
DNSTracker dns_tracker_;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
std::vector<UpstreamAddr> quic_upstream_addrs_;
|
std::vector<UpstreamAddr> quic_upstream_addrs_;
|
||||||
std::vector<std::unique_ptr<QUICListener>> quic_listeners_;
|
std::vector<std::unique_ptr<QUICListener>> quic_listeners_;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
std::shared_ptr<DownstreamConfig> downstreamconf_;
|
std::shared_ptr<DownstreamConfig> downstreamconf_;
|
||||||
std::unique_ptr<MemcachedDispatcher> session_cache_memcached_dispatcher_;
|
std::unique_ptr<MemcachedDispatcher> session_cache_memcached_dispatcher_;
|
||||||
|
@ -360,10 +374,12 @@ private:
|
||||||
SSL_CTX *cl_ssl_ctx_;
|
SSL_CTX *cl_ssl_ctx_;
|
||||||
tls::CertLookupTree *cert_tree_;
|
tls::CertLookupTree *cert_tree_;
|
||||||
ConnectionHandler *conn_handler_;
|
ConnectionHandler *conn_handler_;
|
||||||
|
#ifdef ENABLE_HTTP3
|
||||||
SSL_CTX *quic_sv_ssl_ctx_;
|
SSL_CTX *quic_sv_ssl_ctx_;
|
||||||
tls::CertLookupTree *quic_cert_tree_;
|
tls::CertLookupTree *quic_cert_tree_;
|
||||||
|
|
||||||
QUICConnectionHandler quic_conn_handler_;
|
QUICConnectionHandler quic_conn_handler_;
|
||||||
|
#endif // ENABLE_HTTP3
|
||||||
|
|
||||||
#ifndef HAVE_ATOMIC_STD_SHARED_PTR
|
#ifndef HAVE_ATOMIC_STD_SHARED_PTR
|
||||||
std::mutex ticket_keys_m_;
|
std::mutex ticket_keys_m_;
|
||||||
|
|
Loading…
Reference in New Issue