"http-port 80;\n"
"https-port 443;\n"
"http-listener-clients 300;\n"
+ "http-streams-per-connection 100;\n"
#endif
"\
prefetch 2 9;\n\
EXTERN isc_dscp_t named_g_dscp INIT(-1);
EXTERN in_port_t named_g_http_listener_clients INIT(0);
+EXTERN in_port_t named_g_http_streams_per_conn INIT(0);
EXTERN named_server_t *named_g_server INIT(NULL);
result = named_config_get(maps, "http-listener-clients", &obj);
INSIST(result == ISC_R_SUCCESS);
named_g_http_listener_clients = cfg_obj_asuint32(obj);
+
+ obj = NULL;
+ result = named_config_get(maps, "http-streams-per-connection", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ named_g_http_streams_per_conn = cfg_obj_asuint32(obj);
#endif
/*
const cfg_listelt_t *elt = NULL;
size_t len = 1, i = 0;
uint32_t max_clients = named_g_http_listener_clients;
+ uint32_t max_streams = named_g_http_streams_per_conn;
ns_server_t *server = NULL;
isc_quota_t *quota = NULL;
*/
if (http != NULL) {
const cfg_obj_t *cfg_max_clients = NULL;
+ const cfg_obj_t *cfg_max_streams = NULL;
+
if (cfg_map_get(http, "endpoints", &eplist) == ISC_R_SUCCESS) {
INSIST(eplist != NULL);
len = cfg_list_length(eplist, false);
INSIST(cfg_max_clients != NULL);
max_clients = cfg_obj_asuint32(cfg_max_clients);
}
+
+ if (cfg_map_get(http, "streams-per-connection",
+ &cfg_max_streams) == ISC_R_SUCCESS)
+ {
+ INSIST(cfg_max_streams != NULL);
+ max_streams = cfg_obj_asuint32(cfg_max_streams);
+ }
}
endpoints = isc_mem_allocate(mctx, sizeof(endpoints[0]) * len);
}
result = ns_listenelt_create_http(mctx, port, named_g_dscp, NULL, tls,
key, cert, endpoints, len, quota,
- &delt);
+ max_streams, &delt);
if (result != ISC_R_SUCCESS) {
goto error;
}
http local-http-server {
endpoints { "/dns-query"; };
listener-clients 100;
+ streams-per-connection 100;
};
options {
http-port 80;
https-port 443;
http-listener-clients 100;
+ http-streams-per-connection 100;
listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
};
isc_tlsctx_createserver(NULL, NULL, &tls_ctx);
}
result = isc_nm_listenhttp(netmgr, &sockaddr, 0, NULL, tls_ctx,
- &sock);
+ 0, &sock);
if (result == ISC_R_SUCCESS) {
result = isc_nm_http_endpoint(sock, DEFAULT_DOH_PATH,
read_cb, NULL, 0);
isc_result_t
isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
isc_quota_t *quota, isc_tlsctx_t *ctx,
- isc_nmsocket_t **sockp);
+ uint32_t max_concurrent_streams, isc_nmsocket_t **sockp);
isc_result_t
isc_nm_http_endpoint(isc_nmsocket_t *sock, const char *uri, isc_nm_recv_cb_t cb,
#define MAX_ALLOWED_DATA_IN_POST \
(MAX_DNS_MESSAGE_SIZE + MAX_DNS_MESSAGE_SIZE / 2)
-#define MAX_STREAMS_PER_SESSION (100)
-
#define HEADER_MATCH(header, name, namelen) \
(((namelen) == sizeof(header) - 1) && \
(strncasecmp((header), (const char *)(name), (namelen)) == 0))
size_t bufsize;
isc_tlsctx_t *tlsctx;
+ uint32_t max_concurrent_streams;
isc__nm_http_pending_callbacks_t pending_write_callbacks;
isc_buffer_t *pending_write_data;
return (NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE);
}
- if (session->nsstreams >= MAX_STREAMS_PER_SESSION) {
+ if (session->nsstreams >= session->max_concurrent_streams) {
return (NGHTTP2_ERR_CALLBACK_FAILURE);
}
server_send_connection_header(isc_nm_http_session_t *session) {
nghttp2_settings_entry iv[1] = {
{ NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
- MAX_STREAMS_PER_SESSION }
+ session->max_concurrent_streams }
};
int rv;
http_transpost_tcp_nodelay(handle);
new_session(httplistensock->mgr->mctx, NULL, &session);
+ session->max_concurrent_streams =
+ httplistensock->h2.max_concurrent_streams;
initialize_nghttp2_server_session(session);
handle->sock->h2.session = session;
isc_result_t
isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
isc_quota_t *quota, isc_tlsctx_t *ctx,
- isc_nmsocket_t **sockp) {
+ uint32_t max_concurrent_streams, isc_nmsocket_t **sockp) {
isc_nmsocket_t *sock = NULL;
isc_result_t result;
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;
+
+ if (max_concurrent_streams > 0 &&
+ max_concurrent_streams < NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS)
+ {
+ sock->h2.max_concurrent_streams = max_concurrent_streams;
+ }
if (ctx != NULL) {
isc_tlsctx_enable_http2server_alpn(ctx);
isc_nmsocket_t *httpserver;
+ /* maximum concurrent streams (server-side) */
+ uint32_t max_concurrent_streams;
+
isc_http_request_type_t request_type;
isc_http_scheme_type_t request_scheme;
WILL_RETURN(uv_tcp_bind, UV_EADDRINUSE);
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_not_equal(result, ISC_R_SUCCESS);
assert_null(listen_sock);
char req_url[256];
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH, noop_read_cb, NULL,
0);
char req_url[256];
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH, noop_read_cb, NULL,
char req_url[256];
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
/*
atomic_store(&nsends, atomic_load(&total_sends));
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
atomic_load(&use_TLS) ? server_tlsctx : NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
atomic_store(&nsends, atomic_load(&total_sends));
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
atomic_load(&use_TLS) ? server_tlsctx : NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
atomic_load(&use_TLS) ? server_tlsctx : NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
atomic_store(&nsends, atomic_load(&total_sends));
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
atomic_load(&use_TLS) ? server_tlsctx : NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
atomic_store(&nsends, atomic_load(&total_sends));
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
atomic_load(&use_TLS) ? server_tlsctx : NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
atomic_store(&nsends, atomic_load(&total_sends));
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
atomic_load(&use_TLS) ? server_tlsctx : NULL,
- &listen_sock);
+ 0, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
#if HAVE_LIBNGHTTP2
{ "http-port", &cfg_type_uint32, 0 },
{ "http-listener-clients", &cfg_type_uint32, 0 },
+ { "http-streams-per-connection", &cfg_type_uint32, 0 },
{ "https-port", &cfg_type_uint32, 0 },
#else
{ "http-port", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED },
{ "http-listener-clients", &cfg_type_uint32,
CFG_CLAUSEFLAG_NOTCONFIGURED },
+ { "http-streams-per-connection", &cfg_type_uint32,
+ CFG_CLAUSEFLAG_NOTCONFIGURED },
{ "https-port", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED },
#endif
{ "querylog", &cfg_type_boolean, 0 },
static cfg_clausedef_t cfg_http_description_clauses[] = {
{ "endpoints", &cfg_type_bracketed_http_endpoint_list, 0 },
{ "listener-clients", &cfg_type_uint32, 0 },
+ { "streams-per-connection", &cfg_type_uint32, 0 },
{ NULL, NULL, 0 }
};
char ** http_endpoints;
size_t http_endpoints_number;
isc_quota_t * http_quota;
+ uint32_t max_concurrent_streams;
ISC_LINK(ns_listenelt_t) link;
};
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
dns_acl_t *acl, bool tls, const char *key,
const char *cert, char **endpoints, size_t nendpoints,
- isc_quota_t *quota, ns_listenelt_t **target);
+ isc_quota_t *quota, const uint32_t max_streams,
+ ns_listenelt_t **target);
/*%<
* Create a listen-on list element for HTTP(S).
*/
static isc_result_t
ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps,
- size_t neps, isc_quota_t *quota) {
+ size_t neps, isc_quota_t *quota,
+ uint32_t max_concurrent_streams) {
#if HAVE_LIBNGHTTP2
isc_result_t result;
isc_nmsocket_t *sock = NULL;
result = isc_nm_listenhttp(ifp->mgr->nm, &ifp->addr, ifp->mgr->backlog,
- quota, sslctx, &sock);
+ quota, sslctx, max_concurrent_streams,
+ &sock);
if (result == ISC_R_SUCCESS) {
for (size_t i = 0; i < neps; i++) {
UNUSED(sslctx);
UNUSED(eps);
UNUSED(neps);
+ UNUSED(quota);
+ UNUSED(max_concurrent_streams);
return (ISC_R_NOTIMPLEMENTED);
#endif
}
if (elt->is_http) {
result = ns_interface_listenhttp(
ifp, elt->sslctx, elt->http_endpoints,
- elt->http_endpoints_number, elt->http_quota);
+ elt->http_endpoints_number, elt->http_quota,
+ elt->max_concurrent_streams);
if (result != ISC_R_SUCCESS) {
goto cleanup_interface;
}
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
dns_acl_t *acl, bool tls, const char *key,
const char *cert, char **endpoints, size_t nendpoints,
- isc_quota_t *quota, ns_listenelt_t **target) {
+ isc_quota_t *quota, const uint32_t max_streams,
+ ns_listenelt_t **target) {
isc_result_t result;
REQUIRE(target != NULL && *target == NULL);
(*target)->http_endpoints = endpoints;
(*target)->http_endpoints_number = nendpoints;
(*target)->http_quota = quota;
+ (*target)->max_concurrent_streams = max_streams;
} else {
size_t i;
for (i = 0; i < nendpoints; i++) {