From 886dc93f182aa7ab6570c77013f35494889a2269 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 26 Sep 2021 15:32:44 +0900 Subject: [PATCH] nghttpx: Fail h3 connection attempt if no ALPN is negotiated --- src/shrpx_client_handler.cc | 10 +++++++++- src/shrpx_client_handler.h | 2 ++ src/shrpx_http3_upstream.cc | 8 ++++++++ src/shrpx_tls.cc | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index 234c2b8c..8d02d740 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -517,7 +517,6 @@ void ClientHandler::setup_upstream_io_callback() { void ClientHandler::setup_http3_upstream( std::unique_ptr &&upstream) { upstream_ = std::move(upstream); - alpn_ = StringRef::from_lit("h3"); write_ = &ClientHandler::write_quic; auto config = get_config(); @@ -1599,4 +1598,13 @@ StringRef ClientHandler::get_alpn() const { return alpn_; } BlockAllocator &ClientHandler::get_block_allocator() { return balloc_; } +void ClientHandler::set_alpn_from_conn() { + const unsigned char *alpn; + unsigned int alpnlen; + + SSL_get0_alpn_selected(conn_.tls.ssl, &alpn, &alpnlen); + + alpn_ = make_string_ref(balloc_, StringRef{alpn, alpnlen}); +} + } // namespace shrpx diff --git a/src/shrpx_client_handler.h b/src/shrpx_client_handler.h index 0c013973..f20adc92 100644 --- a/src/shrpx_client_handler.h +++ b/src/shrpx_client_handler.h @@ -187,6 +187,8 @@ public: BlockAllocator &get_block_allocator(); + void set_alpn_from_conn(); + private: // Allocator to allocate memory for connection-wide objects. Make // sure that the allocations must be bounded, and not proportional diff --git a/src/shrpx_http3_upstream.cc b/src/shrpx_http3_upstream.cc index c67d8aae..29d3d9f8 100644 --- a/src/shrpx_http3_upstream.cc +++ b/src/shrpx_http3_upstream.cc @@ -479,6 +479,14 @@ int handshake_completed(ngtcp2_conn *conn, void *user_data) { } // namespace int Http3Upstream::handshake_completed() { + handler_->set_alpn_from_conn(); + + auto alpn = handler_->get_alpn(); + if (alpn.empty()) { + ULOG(ERROR, this) << "NO ALPN was negotiated"; + return -1; + } + std::array token; size_t tokenlen; diff --git a/src/shrpx_tls.cc b/src/shrpx_tls.cc index cda9bbc3..b490c107 100644 --- a/src/shrpx_tls.cc +++ b/src/shrpx_tls.cc @@ -719,7 +719,7 @@ int quic_alpn_select_proto_cb(SSL *ssl, const unsigned char **out, p += 1 + proto_len; } - return SSL_TLSEXT_ERR_NOACK; + return SSL_TLSEXT_ERR_ALERT_FATAL; } } // namespace # endif // OPENSSL_VERSION_NUMBER >= 0x10002000L