2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

Update max concurrent streams limit in HTTP listeners on reconfig

This commit ensures that HTTP listeners concurrent streams limit gets
updated properly on reconfiguration.
This commit is contained in:
Artem Boldariev
2022-06-22 16:45:28 +03:00
parent a2379135fa
commit e72962d5f1
5 changed files with 93 additions and 9 deletions

View File

@@ -129,6 +129,25 @@ isc_nmsocket_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx);
* \li 'tlsctx' is a valid pointer to a TLS context object. * \li 'tlsctx' is a valid pointer to a TLS context object.
*/ */
void
isc_nmsocket_set_max_streams(isc_nmsocket_t *listener,
const uint32_t max_streams);
/*%<
* Set the maximum allowed number of concurrent streams for accepted
* client connections. The implementation might be asynchronous
* depending on the listener socket type.
*
* The call is a no-op for any listener socket type that does not
* support concept of multiple sessions per a client
* connection. Currently, it works only for HTTP/2 listeners.
*
* Setting 'max_streams' to '0' instructs the listener that there is
* no limit for concurrent streams.
*
* Requires:
* \li 'listener' is a pointer to a valid network manager listener socket.
*/
#ifdef NETMGR_TRACE #ifdef NETMGR_TRACE
#define isc_nmhandle_attach(handle, dest) \ #define isc_nmhandle_attach(handle, dest) \
isc__nmhandle_attach(handle, dest, __FILE__, __LINE__, __func__) isc__nmhandle_attach(handle, dest, __FILE__, __LINE__, __func__)
@@ -609,6 +628,21 @@ isc_nm_http_makeuri(const bool https, const isc_sockaddr_t *sa,
* \li 'outbuf' is a valid pointer to a buffer which will get the result; * \li 'outbuf' is a valid pointer to a buffer which will get the result;
* \li 'outbuf_len' is a size of the result buffer and is greater than zero. * \li 'outbuf_len' is a size of the result buffer and is greater than zero.
*/ */
void
isc_nm_http_set_endpoints(isc_nmsocket_t *listener,
isc_nm_http_endpoints_t *eps);
/*%<
* Asynchronously replace the set of HTTP endpoints (paths) within
* the listener socket object. The function is intended to be used
* during reconfiguration.
*
* Requires:
* \li 'listener' is a pointer to a valid network manager listener socket
object with TLS support;
* \li 'eps' is a valid pointer to an HTTP endpoints set.
*/
#endif /* HAVE_LIBNGHTTP2 */ #endif /* HAVE_LIBNGHTTP2 */
void void

View File

@@ -2454,7 +2454,7 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
new_session(httplistensock->mgr->mctx, NULL, &session); new_session(httplistensock->mgr->mctx, NULL, &session);
session->max_concurrent_streams = session->max_concurrent_streams =
httplistensock->h2.max_concurrent_streams; atomic_load(&httplistensock->h2.max_concurrent_streams);
initialize_nghttp2_server_session(session); initialize_nghttp2_server_session(session);
handle->sock->h2.session = session; handle->sock->h2.session = session;
@@ -2481,14 +2481,10 @@ isc_nm_listenhttp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
sock = isc_mem_get(mgr->mctx, sizeof(*sock)); sock = isc_mem_get(mgr->mctx, sizeof(*sock));
isc__nmsocket_init(sock, mgr, isc_nm_httplistener, iface); isc__nmsocket_init(sock, mgr, isc_nm_httplistener, iface);
sock->h2.max_concurrent_streams = atomic_init(&sock->h2.max_concurrent_streams,
NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS; NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS);
if (max_concurrent_streams > 0 && isc_nmsocket_set_max_streams(sock, max_concurrent_streams);
max_concurrent_streams < NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS)
{
sock->h2.max_concurrent_streams = max_concurrent_streams;
}
atomic_store(&eps->in_use, true); atomic_store(&eps->in_use, true);
isc_nm_http_endpoints_attach(eps, &sock->h2.listener_endpoints); isc_nm_http_endpoints_attach(eps, &sock->h2.listener_endpoints);
@@ -2953,6 +2949,23 @@ isc__nm_http_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx) {
isc_nmsocket_set_tlsctx(listener->outer, tlsctx); isc_nmsocket_set_tlsctx(listener->outer, tlsctx);
} }
void
isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
const uint32_t max_concurrent_streams) {
uint32_t max_streams = NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS;
REQUIRE(VALID_NMSOCK(listener));
REQUIRE(listener->type == isc_nm_httplistener);
if (max_concurrent_streams > 0 &&
max_concurrent_streams < NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS)
{
max_streams = max_concurrent_streams;
}
atomic_store(&listener->h2.max_concurrent_streams, max_streams);
}
static const bool base64url_validation_table[256] = { static const bool base64url_validation_table[256] = {
false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,

View File

@@ -872,7 +872,7 @@ typedef struct isc_nmsocket_h2 {
isc_nmsocket_t *httpserver; isc_nmsocket_t *httpserver;
/* maximum concurrent streams (server-side) */ /* maximum concurrent streams (server-side) */
uint32_t max_concurrent_streams; atomic_uint_fast32_t max_concurrent_streams;
uint32_t min_ttl; /* used to set "max-age" in responses */ uint32_t min_ttl; /* used to set "max-age" in responses */
@@ -1817,6 +1817,10 @@ isc__nm_httpsession_detach(isc_nm_http_session_t **sessionp);
void void
isc__nm_http_set_tlsctx(isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx); isc__nm_http_set_tlsctx(isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx);
void
isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
const uint32_t max_concurrent_streams);
#endif #endif
void void

View File

@@ -3373,6 +3373,23 @@ isc_nmsocket_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx) {
}; };
} }
void
isc_nmsocket_set_max_streams(isc_nmsocket_t *listener,
const uint32_t max_streams) {
REQUIRE(VALID_NMSOCK(listener));
switch (listener->type) {
#if HAVE_LIBNGHTTP2
case isc_nm_httplistener:
isc__nm_http_set_max_streams(listener, max_streams);
break;
#endif /* HAVE_LIBNGHTTP2 */
default:
UNUSED(max_streams);
break;
};
return;
}
void void
isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls) { isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls) {
const int log_level = ISC_LOG_DEBUG(1); const int log_level = ISC_LOG_DEBUG(1);

View File

@@ -943,13 +943,26 @@ replace_listener_tlsctx(ns_interface_t *ifp, isc_tlsctx_t *newctx) {
} }
} }
#ifdef HAVE_LIBNGHTTP2
static void static void
update_http_settings(ns_interface_t *ifp, ns_listenelt_t *le) { update_http_settings(ns_interface_t *ifp, ns_listenelt_t *le) {
isc_nmsocket_t *listener;
REQUIRE(le->is_http); REQUIRE(le->is_http);
INSIST(ifp->http_quota != NULL); INSIST(ifp->http_quota != NULL);
isc_quota_max(ifp->http_quota, le->http_max_clients); isc_quota_max(ifp->http_quota, le->http_max_clients);
if (ifp->http_secure_listensocket != NULL) {
listener = ifp->http_secure_listensocket;
} else {
INSIST(ifp->http_listensocket != NULL);
listener = ifp->http_listensocket;
}
isc_nmsocket_set_max_streams(listener, le->max_concurrent_streams);
} }
#endif /* HAVE_LIBNGHTTP2 */
static void static void
update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp, update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
@@ -969,6 +982,7 @@ update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
replace_listener_tlsctx(ifp, le->sslctx); replace_listener_tlsctx(ifp, le->sslctx);
} }
#ifdef HAVE_LIBNGHTTP2
/* /*
* Let's update HTTP listener settings * Let's update HTTP listener settings
* on reconfiguration. * on reconfiguration.
@@ -976,6 +990,8 @@ update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
if (le->is_http) { if (le->is_http) {
update_http_settings(ifp, le); update_http_settings(ifp, le);
} }
#endif /* HAVE_LIBNGHTTP2 */
UNLOCK(&mgr->lock); UNLOCK(&mgr->lock);
} }