2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 08:05:21 +00:00

TLS: try to avoid allocating send request objects

This commit optimises TLS send request object allocation to enable
send request object reuse, somewhat reducing pressure on the memory
manager. It is especially helpful in the case when Stream DNS uses the
TLS implementation as the transport.
This commit is contained in:
Artem Boldariev
2022-12-05 20:19:03 +02:00
parent 4277eeeb9c
commit 56732ac2a0
2 changed files with 52 additions and 15 deletions

View File

@@ -878,6 +878,7 @@ struct isc_nmsocket {
} state; /*%< The order of these is significant */
size_t nsending;
bool tcp_nodelay_value;
isc_nmsocket_tls_send_req_t *send_req; /*%< Send req to reuse */
} tlsstream;
#if HAVE_LIBNGHTTP2

View File

@@ -131,6 +131,9 @@ tls_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
(isc_nmsocket_tls_send_req_t *)cbarg;
isc_nmsocket_t *tlssock = NULL;
bool finish = send_req->finish;
isc_nm_cb_t send_cb = NULL;
void *send_cbarg = NULL;
isc_nmhandle_t *send_handle = NULL;
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
@@ -138,34 +141,52 @@ tls_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
tlssock = send_req->tlssock;
send_req->tlssock = NULL;
send_cb = send_req->cb;
send_cbarg = send_req->cbarg;
send_handle = send_req->handle;
send_req->handle = NULL;
if (finish) {
tls_try_shutdown(tlssock->tlsstream.tls, true);
}
if (send_req->cb != NULL) {
INSIST(VALID_NMHANDLE(tlssock->statichandle));
send_req->cb(send_req->handle, eresult, send_req->cbarg);
isc_nmhandle_detach(&send_req->handle);
/* The last handle has been just detached: close the underlying
* socket. */
if (tlssock->statichandle == NULL) {
finish = true;
}
}
/* We are tying to avoid a memory allocation for small write
/*
* We are tying to avoid a memory allocation for small write
* requests. See the mirroring code in the tls_send_outgoing()
* function. */
* function. The object is attempted to be freed or put for reuse
* before the call to callback because there is a chance that it
* is going to be reused during the call to the callback.
*/
if (send_req->data.length > sizeof(send_req->smallbuf)) {
isc_mem_put(handle->sock->worker->mctx, send_req->data.base,
send_req->data.length);
} else {
INSIST(&send_req->smallbuf[0] == send_req->data.base);
}
isc_mem_put(handle->sock->worker->mctx, send_req, sizeof(*send_req));
send_req->data.base = NULL;
send_req->data.length = 0;
/* Try to keep the object to be reused later - to avoid an allocation */
if (tlssock->tlsstream.send_req == NULL) {
tlssock->tlsstream.send_req = send_req;
} else {
isc_mem_put(handle->sock->worker->mctx, send_req,
sizeof(*send_req));
}
tlssock->tlsstream.nsending--;
if (send_cb != NULL) {
INSIST(VALID_NMHANDLE(tlssock->statichandle));
send_cb(send_handle, eresult, send_cbarg);
isc_nmhandle_detach(&send_handle);
/* The last handle has been just detached: close the underlying
* socket. */
if (tlssock->statichandle == NULL) {
finish = true;
}
}
if (finish && eresult == ISC_R_SUCCESS && tlssock->reading) {
tls_failed_read_cb(tlssock, ISC_R_EOF);
} else if (eresult == ISC_R_SUCCESS) {
@@ -277,7 +298,14 @@ tls_send_outgoing(isc_nmsocket_t *sock, bool finish, isc_nmhandle_t *tlshandle,
pending = TLS_BUF_SIZE;
}
/* Try to reuse previously allocated object */
if (sock->tlsstream.send_req != NULL) {
send_req = sock->tlsstream.send_req;
sock->tlsstream.send_req = NULL;
} else {
send_req = isc_mem_get(sock->worker->mctx, sizeof(*send_req));
}
*send_req = (isc_nmsocket_tls_send_req_t){ .finish = finish,
.data.length = pending };
@@ -1181,6 +1209,14 @@ isc__nm_tls_cleanup_data(isc_nmsocket_t *sock) {
isc_tlsctx_client_session_cache_detach(
&sock->tlsstream.client_sess_cache);
}
if (sock->tlsstream.send_req != NULL) {
INSIST(sock->tlsstream.send_req->data.base == NULL);
INSIST(sock->tlsstream.send_req->data.length == 0);
isc_mem_put(sock->worker->mctx,
sock->tlsstream.send_req,
sizeof(*sock->tlsstream.send_req));
}
} else if (sock->type == isc_nm_tcpsocket &&
sock->tlsstream.tlssocket != NULL)
{