* \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
#define isc_nmhandle_attach(handle, dest) \
isc__nmhandle_attach(handle, dest, __FILE__, __LINE__, __func__)
* \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.
*/
+
+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 */
void
new_session(httplistensock->mgr->mctx, NULL, &session);
session->max_concurrent_streams =
- httplistensock->h2.max_concurrent_streams;
+ atomic_load(&httplistensock->h2.max_concurrent_streams);
initialize_nghttp2_server_session(session);
handle->sock->h2.session = session;
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
isc__nmsocket_init(sock, mgr, isc_nm_httplistener, iface);
- sock->h2.max_concurrent_streams =
- NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS;
+ atomic_init(&sock->h2.max_concurrent_streams,
+ NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS);
- if (max_concurrent_streams > 0 &&
- max_concurrent_streams < NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS)
- {
- sock->h2.max_concurrent_streams = max_concurrent_streams;
- }
+ isc_nmsocket_set_max_streams(sock, max_concurrent_streams);
atomic_store(&eps->in_use, true);
isc_nm_http_endpoints_attach(eps, &sock->h2.listener_endpoints);
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] = {
false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false,
isc_nmsocket_t *httpserver;
/* 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 */
void
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
void
};
}
+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
isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls) {
const int log_level = ISC_LOG_DEBUG(1);
}
}
+#ifdef HAVE_LIBNGHTTP2
static void
update_http_settings(ns_interface_t *ifp, ns_listenelt_t *le) {
+ isc_nmsocket_t *listener;
+
REQUIRE(le->is_http);
INSIST(ifp->http_quota != NULL);
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
update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
replace_listener_tlsctx(ifp, le->sslctx);
}
+#ifdef HAVE_LIBNGHTTP2
/*
* Let's update HTTP listener settings
* on reconfiguration.
if (le->is_http) {
update_http_settings(ifp, le);
}
+#endif /* HAVE_LIBNGHTTP2 */
+
UNLOCK(&mgr->lock);
}