Update the set of HTTP endpoints on reconfiguration

This commit ensures that on reconfiguration the set of HTTP
endpoints (=paths) is being updated within HTTP listeners.

(cherry picked from commit d2e13ddf22)
This commit is contained in:
Artem Boldariev
2022-06-22 19:31:18 +03:00
parent bb8ba2c027
commit b6b07c5646
5 changed files with 206 additions and 19 deletions

View File

@@ -179,6 +179,9 @@ typedef struct isc_http_send_req {
isc__nm_http_pending_callbacks_t pending_write_callbacks;
} isc_http_send_req_t;
#define HTTP_ENDPOINTS_MAGIC ISC_MAGIC('H', 'T', 'E', 'P')
#define VALID_HTTP_ENDPOINTS(t) ISC_MAGIC_VALID(t, HTTP_ENDPOINTS_MAGIC)
static bool
http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
isc_nm_cb_t cb, void *cbarg);
@@ -225,6 +228,16 @@ static isc_nm_httphandler_t *
http_endpoints_find(const char *request_path,
const isc_nm_http_endpoints_t *restrict eps);
static void
http_init_listener_endpoints(isc_nmsocket_t *listener,
isc_nm_http_endpoints_t *epset);
static void
http_cleanup_listener_endpoints(isc_nmsocket_t *listener);
static isc_nm_http_endpoints_t *
http_get_listener_endpoints(isc_nmsocket_t *listener, const int tid);
static bool
http_session_active(isc_nm_http_session_t *session) {
REQUIRE(VALID_HTTP2_SESSION(session));
@@ -1654,14 +1667,15 @@ server_on_begin_headers_callback(nghttp2_session *ngsession,
static isc_nm_httphandler_t *
find_server_request_handler(const char *request_path,
const isc_nmsocket_t *serversocket) {
isc_nmsocket_t *serversocket, const int tid) {
isc_nm_httphandler_t *handler = NULL;
REQUIRE(VALID_NMSOCK(serversocket));
if (atomic_load(&serversocket->listening)) {
handler = http_endpoints_find(
request_path, serversocket->h2.listener_endpoints);
request_path,
http_get_listener_endpoints(serversocket, tid));
}
return (handler);
}
@@ -1691,7 +1705,8 @@ server_handle_path_header(isc_nmsocket_t *socket, const uint8_t *value,
}
handler = find_server_request_handler(socket->h2.request_path,
socket->h2.session->serversocket);
socket->h2.session->serversocket,
socket->tid);
if (handler != NULL) {
socket->h2.cb = handler->cb;
socket->h2.cbarg = handler->cbarg;
@@ -2487,7 +2502,7 @@ isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
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);
http_init_listener_endpoints(sock, eps);
if (ctx != NULL) {
result = isc_nm_listentls(mgr, iface, httplisten_acceptcb, sock,
@@ -2530,6 +2545,7 @@ isc_nm_http_endpoints_new(isc_mem_t *mctx) {
ISC_LIST_INIT(eps->handlers);
isc_refcount_init(&eps->references, 1);
atomic_init(&eps->in_use, false);
eps->magic = HTTP_ENDPOINTS_MAGIC;
return eps;
}
@@ -2543,9 +2559,10 @@ isc_nm_http_endpoints_detach(isc_nm_http_endpoints_t **restrict epsp) {
REQUIRE(epsp != NULL);
eps = *epsp;
REQUIRE(eps != NULL);
REQUIRE(VALID_HTTP_ENDPOINTS(eps));
if (isc_refcount_decrement(&eps->references) > 1) {
*epsp = NULL;
return;
}
@@ -2573,6 +2590,8 @@ isc_nm_http_endpoints_detach(isc_nm_http_endpoints_t **restrict epsp) {
httpcbarg = next;
}
eps->magic = 0;
isc_mem_putanddetach(&mctx, eps, sizeof(*eps));
*epsp = NULL;
}
@@ -2580,6 +2599,7 @@ isc_nm_http_endpoints_detach(isc_nm_http_endpoints_t **restrict epsp) {
void
isc_nm_http_endpoints_attach(isc_nm_http_endpoints_t *source,
isc_nm_http_endpoints_t **targetp) {
REQUIRE(VALID_HTTP_ENDPOINTS(source));
REQUIRE(targetp != NULL && *targetp == NULL);
isc_refcount_increment(&source->references);
@@ -2592,6 +2612,8 @@ http_endpoints_find(const char *request_path,
const isc_nm_http_endpoints_t *restrict eps) {
isc_nm_httphandler_t *handler = NULL;
REQUIRE(VALID_HTTP_ENDPOINTS(eps));
if (request_path == NULL || *request_path == '\0') {
return (NULL);
}
@@ -2637,7 +2659,7 @@ isc_nm_http_endpoints_add(isc_nm_http_endpoints_t *restrict eps,
isc_nm_httpcbarg_t *restrict httpcbarg = NULL;
bool newhandler = false;
REQUIRE(eps != NULL);
REQUIRE(VALID_HTTP_ENDPOINTS(eps));
REQUIRE(isc_nm_http_path_isvalid(uri));
REQUIRE(atomic_load(&eps->in_use) == false);
@@ -2968,6 +2990,93 @@ isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
atomic_store(&listener->h2.max_concurrent_streams, max_streams);
}
void
isc_nm_http_set_endpoints(isc_nmsocket_t *listener,
isc_nm_http_endpoints_t *eps) {
size_t nworkers;
REQUIRE(VALID_NMSOCK(listener));
REQUIRE(listener->type == isc_nm_httplistener);
REQUIRE(VALID_HTTP_ENDPOINTS(eps));
atomic_store(&eps->in_use, true);
nworkers = (size_t)listener->mgr->nworkers;
for (size_t i = 0; i < nworkers; i++) {
isc__netievent__http_eps_t *ievent =
isc__nm_get_netievent_httpendpoints(listener->mgr,
listener, eps);
isc__nm_enqueue_ievent(&listener->mgr->workers[i],
(isc__netievent_t *)ievent);
}
}
void
isc__nm_async_httpendpoints(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent__http_eps_t *ievent = (isc__netievent__http_eps_t *)ev0;
const int tid = isc_nm_tid();
isc_nmsocket_t *listener = ievent->sock;
isc_nm_http_endpoints_t *eps = ievent->endpoints;
UNUSED(worker);
isc_nm_http_endpoints_detach(&listener->h2.listener_endpoints[tid]);
isc_nm_http_endpoints_attach(eps,
&listener->h2.listener_endpoints[tid]);
}
static void
http_init_listener_endpoints(isc_nmsocket_t *listener,
isc_nm_http_endpoints_t *epset) {
size_t nworkers;
REQUIRE(VALID_NMSOCK(listener));
REQUIRE(VALID_NM(listener->mgr));
REQUIRE(VALID_HTTP_ENDPOINTS(epset));
nworkers = (size_t)listener->mgr->nworkers;
INSIST(nworkers > 0);
listener->h2.listener_endpoints =
isc_mem_get(listener->mgr->mctx,
sizeof(isc_nm_http_endpoints_t *) * nworkers);
listener->h2.n_listener_endpoints = nworkers;
for (size_t i = 0; i < nworkers; i++) {
listener->h2.listener_endpoints[i] = NULL;
isc_nm_http_endpoints_attach(
epset, &listener->h2.listener_endpoints[i]);
}
}
static void
http_cleanup_listener_endpoints(isc_nmsocket_t *listener) {
REQUIRE(VALID_NM(listener->mgr));
if (listener->h2.listener_endpoints == NULL) {
return;
}
for (size_t i = 0; i < listener->h2.n_listener_endpoints; i++) {
isc_nm_http_endpoints_detach(
&listener->h2.listener_endpoints[i]);
}
isc_mem_put(listener->mgr->mctx, listener->h2.listener_endpoints,
sizeof(isc_nm_http_endpoints_t *) *
listener->h2.n_listener_endpoints);
listener->h2.n_listener_endpoints = 0;
}
static isc_nm_http_endpoints_t *
http_get_listener_endpoints(isc_nmsocket_t *listener, const int tid) {
isc_nm_http_endpoints_t *eps;
REQUIRE(VALID_NMSOCK(listener));
REQUIRE(tid >= 0);
REQUIRE((size_t)tid < listener->h2.n_listener_endpoints);
eps = listener->h2.listener_endpoints[tid];
INSIST(eps != NULL);
return (eps);
}
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,
@@ -3121,8 +3230,7 @@ isc__nm_http_cleanup_data(isc_nmsocket_t *sock) {
if (sock->type == isc_nm_httplistener &&
sock->h2.listener_endpoints != NULL) {
/* Delete all handlers */
isc_nm_http_endpoints_detach(
&sock->h2.listener_endpoints);
http_cleanup_listener_endpoints(sock);
}
if (sock->h2.request_path != NULL) {