nghttpx: Add HTTP3 skeleton and minor SSL_CTX fix
This commit is contained in:
parent
387d3aab09
commit
544882ca0e
|
@ -345,7 +345,8 @@ int ConnectionHandler::create_worker_thread(size_t num) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
# endif // HAVE_MRUBY
|
# endif // HAVE_MRUBY
|
||||||
if (worker->setup_quic_server_socket() != 0) {
|
if ((!apiconf.enabled || i != 0) &&
|
||||||
|
worker->setup_quic_server_socket() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ fail:
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Http3Upstream::Http3Upstream(ClientHandler *handler)
|
Http3Upstream::Http3Upstream(ClientHandler *handler)
|
||||||
: handler_{handler}, conn_{nullptr}, tls_alert_{0} {
|
: handler_{handler}, conn_{nullptr}, tls_alert_{0}, httpconn_{nullptr} {
|
||||||
ev_timer_init(&timer_, timeoutcb, 0., 0.);
|
ev_timer_init(&timer_, timeoutcb, 0., 0.);
|
||||||
timer_.data = this;
|
timer_.data = this;
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@ Http3Upstream::~Http3Upstream() {
|
||||||
ev_timer_stop(loop, &idle_timer_);
|
ev_timer_stop(loop, &idle_timer_);
|
||||||
ev_timer_stop(loop, &timer_);
|
ev_timer_stop(loop, &timer_);
|
||||||
|
|
||||||
|
nghttp3_conn_del(httpconn_);
|
||||||
|
|
||||||
if (conn_) {
|
if (conn_) {
|
||||||
auto worker = handler_->get_worker();
|
auto worker = handler_->get_worker();
|
||||||
auto quic_client_handler = worker->get_quic_connection_handler();
|
auto quic_client_handler = worker->get_quic_connection_handler();
|
||||||
|
@ -594,6 +596,10 @@ int Http3Upstream::on_tx_secret(ngtcp2_crypto_level level,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (level == NGTCP2_CRYPTO_LEVEL_APPLICATION && setup_httpconn() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,4 +654,160 @@ void Http3Upstream::reset_timer() {
|
||||||
ev_timer_again(handler_->get_loop(), &timer_);
|
ev_timer_again(handler_->get_loop(), &timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_deferred_consume(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
size_t nsoncumed, void *user_data,
|
||||||
|
void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
size_t datalen, void *user_data,
|
||||||
|
void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_begin_request_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
void *user_data, void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_recv_request_header(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
int32_t token, nghttp3_rcbuf *name,
|
||||||
|
nghttp3_rcbuf *value, uint8_t flags,
|
||||||
|
void *user_data, void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_end_request_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
void *user_data, void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_recv_data(nghttp3_conn *conn, int64_t stream_id, const uint8_t *data,
|
||||||
|
size_t datalen, void *user_data, void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_end_stream(nghttp3_conn *conn, int64_t stream_id, void *user_data,
|
||||||
|
void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_stream_close(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
uint64_t app_error_code, void *conn_user_data,
|
||||||
|
void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_send_stop_sending(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
uint64_t app_error_code, void *user_data,
|
||||||
|
void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int http_reset_stream(nghttp3_conn *conn, int64_t stream_id,
|
||||||
|
uint64_t app_error_code, void *user_data,
|
||||||
|
void *stream_user_data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int Http3Upstream::setup_httpconn() {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (ngtcp2_conn_get_max_local_streams_uni(conn_) < 3) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp3_callbacks callbacks{
|
||||||
|
http_acked_stream_data,
|
||||||
|
http_stream_close,
|
||||||
|
http_recv_data,
|
||||||
|
http_deferred_consume,
|
||||||
|
http_begin_request_headers,
|
||||||
|
http_recv_request_header,
|
||||||
|
http_end_request_headers,
|
||||||
|
nullptr, // begin_trailers
|
||||||
|
nullptr, // recv_trailer
|
||||||
|
nullptr, // end_trailers
|
||||||
|
http_send_stop_sending,
|
||||||
|
http_end_stream,
|
||||||
|
http_reset_stream,
|
||||||
|
};
|
||||||
|
|
||||||
|
nghttp3_settings settings;
|
||||||
|
nghttp3_settings_default(&settings);
|
||||||
|
settings.qpack_max_table_capacity = 4_k;
|
||||||
|
|
||||||
|
auto mem = nghttp3_mem_default();
|
||||||
|
|
||||||
|
rv = nghttp3_conn_server_new(&httpconn_, &callbacks, &settings, mem, this);
|
||||||
|
if (rv != 0) {
|
||||||
|
LOG(ERROR) << "nghttp3_conn_server_new: " << nghttp3_strerror(rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngtcp2_transport_params params;
|
||||||
|
ngtcp2_conn_get_local_transport_params(conn_, ¶ms);
|
||||||
|
|
||||||
|
nghttp3_conn_set_max_client_streams_bidi(httpconn_,
|
||||||
|
params.initial_max_streams_bidi);
|
||||||
|
|
||||||
|
int64_t ctrl_stream_id;
|
||||||
|
|
||||||
|
rv = ngtcp2_conn_open_uni_stream(conn_, &ctrl_stream_id, nullptr);
|
||||||
|
if (rv != 0) {
|
||||||
|
LOG(ERROR) << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = nghttp3_conn_bind_control_stream(httpconn_, ctrl_stream_id);
|
||||||
|
if (rv != 0) {
|
||||||
|
LOG(ERROR) << "nghttp3_conn_bind_control_stream: " << nghttp3_strerror(rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t qpack_enc_stream_id, qpack_dec_stream_id;
|
||||||
|
|
||||||
|
rv = ngtcp2_conn_open_uni_stream(conn_, &qpack_enc_stream_id, nullptr);
|
||||||
|
if (rv != 0) {
|
||||||
|
LOG(ERROR) << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = ngtcp2_conn_open_uni_stream(conn_, &qpack_dec_stream_id, nullptr);
|
||||||
|
if (rv != 0) {
|
||||||
|
LOG(ERROR) << "ngtcp2_conn_open_uni_stream: " << ngtcp2_strerror(rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = nghttp3_conn_bind_qpack_streams(httpconn_, qpack_enc_stream_id,
|
||||||
|
qpack_dec_stream_id);
|
||||||
|
if (rv != 0) {
|
||||||
|
LOG(ERROR) << "nghttp3_conn_bind_qpack_streams: " << nghttp3_strerror(rv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "shrpx.h"
|
#include "shrpx.h"
|
||||||
|
|
||||||
#include <ngtcp2/ngtcp2.h>
|
#include <ngtcp2/ngtcp2.h>
|
||||||
|
#include <nghttp3/nghttp3.h>
|
||||||
|
|
||||||
#include "shrpx_upstream.h"
|
#include "shrpx_upstream.h"
|
||||||
#include "quic.h"
|
#include "quic.h"
|
||||||
|
@ -109,6 +110,8 @@ public:
|
||||||
void reset_idle_timer();
|
void reset_idle_timer();
|
||||||
void reset_timer();
|
void reset_timer();
|
||||||
|
|
||||||
|
int setup_httpconn();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientHandler *handler_;
|
ClientHandler *handler_;
|
||||||
ev_timer timer_;
|
ev_timer timer_;
|
||||||
|
@ -117,6 +120,7 @@ private:
|
||||||
ngtcp2_conn *conn_;
|
ngtcp2_conn *conn_;
|
||||||
quic::Error last_error_;
|
quic::Error last_error_;
|
||||||
uint8_t tls_alert_;
|
uint8_t tls_alert_;
|
||||||
|
nghttp3_conn *httpconn_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -185,7 +185,8 @@ 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};
|
||||||
|
|
||||||
auto cert_tree = worker->get_cert_lookup_tree();
|
auto cert_tree = SSL_is_quic(ssl) ? worker->get_quic_cert_lookup_tree()
|
||||||
|
: worker->get_cert_lookup_tree();
|
||||||
|
|
||||||
auto idx = cert_tree->lookup(hostname);
|
auto idx = cert_tree->lookup(hostname);
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
|
@ -196,7 +197,9 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
|
||||||
|
|
||||||
auto conn_handler = worker->get_connection_handler();
|
auto conn_handler = worker->get_connection_handler();
|
||||||
|
|
||||||
const auto &ssl_ctx_list = conn_handler->get_indexed_ssl_ctx(idx);
|
const auto &ssl_ctx_list = SSL_is_quic(ssl)
|
||||||
|
? conn_handler->get_quic_indexed_ssl_ctx(idx)
|
||||||
|
: conn_handler->get_indexed_ssl_ctx(idx);
|
||||||
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 && \
|
||||||
|
|
Loading…
Reference in New Issue