mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
DoH: close active server streams when finishing session
Under some circumstances a situation might occur when server-side session gets finished while there are still active HTTP/2 streams. This would lead to isc_nm_httpsocket object leaks. This commit fixes this behaviour as well as refactors failed_read_cb() to allow better code reuse.
This commit is contained in:
@@ -165,6 +165,12 @@ static void
|
|||||||
failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
||||||
isc_nm_http_session_t *session);
|
isc_nm_http_session_t *session);
|
||||||
|
|
||||||
|
static void
|
||||||
|
client_call_failed_read_cb(isc_result_t result, isc_nm_http_session_t *session);
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_call_failed_read_cb(isc_result_t result, isc_nm_http_session_t *session);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
failed_read_cb(isc_result_t result, isc_nm_http_session_t *session);
|
failed_read_cb(isc_result_t result, isc_nm_http_session_t *session);
|
||||||
|
|
||||||
@@ -420,23 +426,10 @@ finish_http_session(isc_nm_http_session_t *session) {
|
|||||||
isc_nm_cancelread(session->handle);
|
isc_nm_cancelread(session->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ISC_LIST_EMPTY(session->cstreams)) {
|
if (session->client) {
|
||||||
http_cstream_t *cstream =
|
client_call_failed_read_cb(ISC_R_UNEXPECTED, session);
|
||||||
ISC_LIST_HEAD(session->cstreams);
|
} else {
|
||||||
while (cstream != NULL) {
|
server_call_failed_read_cb(ISC_R_UNEXPECTED, session);
|
||||||
http_cstream_t *next = ISC_LIST_NEXT(cstream,
|
|
||||||
link);
|
|
||||||
ISC_LIST_DEQUEUE(session->cstreams, cstream,
|
|
||||||
link);
|
|
||||||
cstream->read_cb(
|
|
||||||
session->client_httphandle,
|
|
||||||
ISC_R_UNEXPECTED,
|
|
||||||
&(isc_region_t){ cstream->rbuf,
|
|
||||||
cstream->rbufsize },
|
|
||||||
cstream->read_cbarg);
|
|
||||||
put_http_cstream(session->mctx, cstream);
|
|
||||||
cstream = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
isc_nmhandle_detach(&session->handle);
|
isc_nmhandle_detach(&session->handle);
|
||||||
}
|
}
|
||||||
@@ -2401,29 +2394,63 @@ failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
failed_read_cb(isc_result_t result, isc_nm_http_session_t *session) {
|
client_call_failed_read_cb(isc_result_t result,
|
||||||
|
isc_nm_http_session_t *session) {
|
||||||
|
http_cstream_t *cstream = NULL;
|
||||||
|
|
||||||
REQUIRE(VALID_HTTP2_SESSION(session));
|
REQUIRE(VALID_HTTP2_SESSION(session));
|
||||||
REQUIRE(result != ISC_R_SUCCESS);
|
REQUIRE(result != ISC_R_SUCCESS);
|
||||||
|
|
||||||
if (session->client) {
|
cstream = ISC_LIST_HEAD(session->cstreams);
|
||||||
http_cstream_t *cstream = NULL;
|
while (cstream != NULL) {
|
||||||
cstream = ISC_LIST_HEAD(session->cstreams);
|
http_cstream_t *next = ISC_LIST_NEXT(cstream, link);
|
||||||
while (cstream != NULL) {
|
cstream->read_cb(
|
||||||
http_cstream_t *next = ISC_LIST_NEXT(cstream, link);
|
session->client_httphandle, result,
|
||||||
cstream->read_cb(session->client_httphandle, result,
|
&(isc_region_t){ cstream->rbuf, cstream->rbufsize },
|
||||||
&(isc_region_t){ cstream->rbuf,
|
cstream->read_cbarg);
|
||||||
cstream->rbufsize },
|
|
||||||
cstream->read_cbarg);
|
if (result != ISC_R_TIMEDOUT ||
|
||||||
if (result != ISC_R_TIMEDOUT ||
|
!isc__nmsocket_timer_running(session->handle->sock))
|
||||||
!isc__nmsocket_timer_running(session->handle->sock))
|
{
|
||||||
{
|
ISC_LIST_DEQUEUE(session->cstreams, cstream, link);
|
||||||
ISC_LIST_DEQUEUE(session->cstreams, cstream,
|
put_http_cstream(session->mctx, cstream);
|
||||||
link);
|
|
||||||
put_http_cstream(session->mctx, cstream);
|
|
||||||
}
|
|
||||||
cstream = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cstream = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_call_failed_read_cb(isc_result_t result,
|
||||||
|
isc_nm_http_session_t *session) {
|
||||||
|
isc_nmsocket_h2_t *h2data = NULL; /* stream socket */
|
||||||
|
|
||||||
|
REQUIRE(VALID_HTTP2_SESSION(session));
|
||||||
|
REQUIRE(result != ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
for (h2data = ISC_LIST_HEAD(session->sstreams); h2data != NULL;
|
||||||
|
h2data = ISC_LIST_NEXT(h2data, link))
|
||||||
|
{
|
||||||
|
failed_httpstream_read_cb(h2data->psock, result, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2data = ISC_LIST_HEAD(session->sstreams);
|
||||||
|
while (h2data != NULL) {
|
||||||
|
isc_nmsocket_h2_t *next = ISC_LIST_NEXT(h2data, link);
|
||||||
|
ISC_LIST_DEQUEUE(session->sstreams, h2data, link);
|
||||||
|
/* Cleanup socket in place */
|
||||||
|
atomic_store(&h2data->psock->active, false);
|
||||||
|
atomic_store(&h2data->psock->closed, true);
|
||||||
|
isc__nmsocket_detach(&h2data->psock);
|
||||||
|
|
||||||
|
h2data = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
failed_read_cb(isc_result_t result, isc_nm_http_session_t *session) {
|
||||||
|
if (session->client) {
|
||||||
|
client_call_failed_read_cb(result, session);
|
||||||
/*
|
/*
|
||||||
* If result was ISC_R_TIMEDOUT and the timer was reset,
|
* If result was ISC_R_TIMEDOUT and the timer was reset,
|
||||||
* then we still have active streams and should not close
|
* then we still have active streams and should not close
|
||||||
@@ -2433,26 +2460,7 @@ failed_read_cb(isc_result_t result, isc_nm_http_session_t *session) {
|
|||||||
finish_http_session(session);
|
finish_http_session(session);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isc_nmsocket_h2_t *h2data = NULL; /* stream socket */
|
server_call_failed_read_cb(result, session);
|
||||||
for (h2data = ISC_LIST_HEAD(session->sstreams); h2data != NULL;
|
|
||||||
h2data = ISC_LIST_NEXT(h2data, link))
|
|
||||||
{
|
|
||||||
failed_httpstream_read_cb(h2data->psock, result,
|
|
||||||
session);
|
|
||||||
}
|
|
||||||
|
|
||||||
h2data = ISC_LIST_HEAD(session->sstreams);
|
|
||||||
while (h2data != NULL) {
|
|
||||||
isc_nmsocket_h2_t *next = ISC_LIST_NEXT(h2data, link);
|
|
||||||
ISC_LIST_DEQUEUE(session->sstreams, h2data, link);
|
|
||||||
/* Cleanup socket in place */
|
|
||||||
atomic_store(&h2data->psock->active, false);
|
|
||||||
atomic_store(&h2data->psock->closed, true);
|
|
||||||
isc__nmsocket_detach(&h2data->psock);
|
|
||||||
|
|
||||||
h2data = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All streams are now destroyed; close the session.
|
* All streams are now destroyed; close the session.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user