mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Disable Nagle's algorithm for HTTP/2 connections
It is advisable to disable Nagle's algorithm for HTTP/2 connections because multiple HTTP/2 streams could be multiplexed over one transport connection. Thus, delays when delivering small packets could bring down performance for the whole session. HTTP/2 is meant to be used this way.
This commit is contained in:
parent
66d20cf28b
commit
7a59fb8207
@ -170,6 +170,9 @@ client_send(isc_nmhandle_t *handle, const isc_region_t *region);
|
|||||||
static void
|
static void
|
||||||
finish_http_session(isc_nm_http_session_t *session);
|
finish_http_session(isc_nm_http_session_t *session);
|
||||||
|
|
||||||
|
static void
|
||||||
|
http_transpost_tcp_nodelay(isc_nmhandle_t *transphandle);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
http_session_active(isc_nm_http_session_t *session) {
|
http_session_active(isc_nm_http_session_t *session) {
|
||||||
REQUIRE(VALID_HTTP2_SESSION(session));
|
REQUIRE(VALID_HTTP2_SESSION(session));
|
||||||
@ -867,7 +870,7 @@ http_writecb(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||||||
INSIST(session->handle == handle);
|
INSIST(session->handle == handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->cb) {
|
if (req->cb != NULL) {
|
||||||
req->cb(req->httphandle, result, req->cbarg);
|
req->cb(req->httphandle, result, req->cbarg);
|
||||||
isc_nmhandle_detach(&req->httphandle);
|
isc_nmhandle_detach(&req->httphandle);
|
||||||
}
|
}
|
||||||
@ -1094,6 +1097,7 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http_transpost_tcp_nodelay(handle);
|
||||||
http_call_connect_cb(http_sock, result);
|
http_call_connect_cb(http_sock, result);
|
||||||
http_do_bio(session, NULL, NULL, NULL);
|
http_do_bio(session, NULL, NULL, NULL);
|
||||||
isc__nmsocket_detach(&http_sock);
|
isc__nmsocket_detach(&http_sock);
|
||||||
@ -1678,7 +1682,7 @@ server_on_request_recv(nghttp2_session *ngsession,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!socket->h2.request_path || !socket->h2.cb) {
|
if (socket->h2.request_path == NULL || socket->h2.cb == NULL) {
|
||||||
code = ISC_HTTP_ERROR_NOT_FOUND;
|
code = ISC_HTTP_ERROR_NOT_FOUND;
|
||||||
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST &&
|
} else if (socket->h2.request_type == ISC_HTTP_REQ_POST &&
|
||||||
socket->h2.bufsize > socket->h2.content_length)
|
socket->h2.bufsize > socket->h2.content_length)
|
||||||
@ -1975,6 +1979,31 @@ server_send_connection_header(isc_nm_http_session_t *session) {
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It is advisable to disable Nagle's algorithm for HTTP/2
|
||||||
|
* connections because multiple HTTP/2 streams could be multiplexed
|
||||||
|
* over one transport connection. Thus, delays when delivering small
|
||||||
|
* packets could bring down performance for the whole session.
|
||||||
|
* HTTP/2 is meant to be used this way.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
http_transpost_tcp_nodelay(isc_nmhandle_t *transphandle) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
isc_nmsocket_t *tcpsock = NULL;
|
||||||
|
uv_os_fd_t tcp_fd = (uv_os_fd_t)-1;
|
||||||
|
|
||||||
|
if (transphandle->sock->type == isc_nm_tlssocket) {
|
||||||
|
tcpsock = transphandle->sock->outerhandle->sock;
|
||||||
|
} else {
|
||||||
|
tcpsock = transphandle->sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)uv_fileno((uv_handle_t *)&tcpsock->uv_handle.tcp, &tcp_fd);
|
||||||
|
RUNTIME_CHECK(tcp_fd != (uv_os_fd_t)-1);
|
||||||
|
(void)isc__nm_socket_tcp_nodelay((uv_os_sock_t)tcp_fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||||
isc_nmsocket_t *httplistensock = (isc_nmsocket_t *)cbarg;
|
isc_nmsocket_t *httplistensock = (isc_nmsocket_t *)cbarg;
|
||||||
@ -1983,6 +2012,7 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||||||
|
|
||||||
REQUIRE(VALID_NMHANDLE(handle));
|
REQUIRE(VALID_NMHANDLE(handle));
|
||||||
REQUIRE(VALID_NMSOCK(handle->sock));
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||||
|
|
||||||
if (handle->sock->type == isc_nm_tlssocket) {
|
if (handle->sock->type == isc_nm_tlssocket) {
|
||||||
REQUIRE(VALID_NMSOCK(handle->sock->listener));
|
REQUIRE(VALID_NMSOCK(handle->sock->listener));
|
||||||
listener = handle->sock->listener;
|
listener = handle->sock->listener;
|
||||||
@ -2016,6 +2046,8 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||||||
return (ISC_R_CANCELED);
|
return (ISC_R_CANCELED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http_transpost_tcp_nodelay(handle);
|
||||||
|
|
||||||
new_session(httplistensock->mgr->mctx, NULL, &session);
|
new_session(httplistensock->mgr->mctx, NULL, &session);
|
||||||
initialize_nghttp2_server_session(session);
|
initialize_nghttp2_server_session(session);
|
||||||
handle->sock->h2.session = session;
|
handle->sock->h2.session = session;
|
||||||
@ -2249,7 +2281,7 @@ failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
|||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
INSIST(sock->type == isc_nm_httpsocket);
|
INSIST(sock->type == isc_nm_httpsocket);
|
||||||
|
|
||||||
if (!sock->h2.request_path) {
|
if (sock->h2.request_path == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2378,7 +2410,7 @@ isc__nm_base64url_to_base64(isc_mem_t *mem, const char *base64url,
|
|||||||
|
|
||||||
INSIST(i == len);
|
INSIST(i == len);
|
||||||
|
|
||||||
if (res_len) {
|
if (res_len != NULL) {
|
||||||
*res_len = len;
|
*res_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,6 +1687,12 @@ isc__nm_socket_connectiontimeout(uv_os_sock_t fd, int timeout_ms);
|
|||||||
* the minimum value must be at least 1000 (1 second).
|
* the minimum value must be at least 1000 (1 second).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc__nm_socket_tcp_nodelay(uv_os_sock_t fd);
|
||||||
|
/*%<
|
||||||
|
* Disables Nagle's algorithm on a TCP socket (sets TCP_NODELAY).
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* typedef all the netievent types
|
* typedef all the netievent types
|
||||||
*/
|
*/
|
||||||
|
@ -2407,6 +2407,20 @@ isc__nm_socket_connectiontimeout(uv_os_sock_t fd, int timeout_ms) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc__nm_socket_tcp_nodelay(uv_os_sock_t fd) {
|
||||||
|
#ifdef TCP_NODELAY
|
||||||
|
if (setsockopt_on(fd, IPPROTO_TCP, TCP_NODELAY) == -1) {
|
||||||
|
return (ISC_R_FAILURE);
|
||||||
|
} else {
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UNUSED(fd);
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NETMGR_TRACE
|
#ifdef NETMGR_TRACE
|
||||||
/*
|
/*
|
||||||
* Dump all active sockets in netmgr. We output to stderr
|
* Dump all active sockets in netmgr. We output to stderr
|
||||||
|
@ -410,6 +410,7 @@ tls_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
|
|||||||
REQUIRE(VALID_NMSOCK(tlssock));
|
REQUIRE(VALID_NMSOCK(tlssock));
|
||||||
REQUIRE(VALID_NMHANDLE(handle));
|
REQUIRE(VALID_NMHANDLE(handle));
|
||||||
REQUIRE(tlssock->tid == isc_nm_tid());
|
REQUIRE(tlssock->tid == isc_nm_tid());
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
tls_failed_read_cb(tlssock, tlssock->statichandle, result);
|
tls_failed_read_cb(tlssock, tlssock->statichandle, result);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user