mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
Merge branch 'artem/doh-no-rwlocks' into 'main'
Get rid of RW locks in the DoH code See merge request isc-projects/bind9!5278
This commit is contained in:
@@ -286,15 +286,19 @@ run(void) {
|
||||
case HTTPS:
|
||||
case HTTP: {
|
||||
bool is_https = protocol == HTTPS;
|
||||
isc_nm_http_endpoints_t *eps = NULL;
|
||||
if (is_https) {
|
||||
isc_tlsctx_createserver(NULL, NULL, &tls_ctx);
|
||||
}
|
||||
result = isc_nm_listenhttp(netmgr, &sockaddr, 0, NULL, tls_ctx,
|
||||
0, &sock);
|
||||
eps = isc_nm_http_endpoints_new(mctx);
|
||||
result = isc_nm_http_endpoints_add(eps, DEFAULT_DOH_PATH,
|
||||
read_cb, NULL, 0);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = isc_nm_http_endpoint(sock, DEFAULT_DOH_PATH,
|
||||
read_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(netmgr, &sockaddr, 0, NULL,
|
||||
tls_ctx, eps, 0, &sock);
|
||||
}
|
||||
isc_nm_http_endpoints_detach(&eps);
|
||||
} break;
|
||||
#endif
|
||||
default:
|
||||
|
@@ -499,11 +499,56 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
isc_result_t
|
||||
isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
|
||||
isc_quota_t *quota, isc_tlsctx_t *ctx,
|
||||
uint32_t max_concurrent_streams, isc_nmsocket_t **sockp);
|
||||
isc_nm_http_endpoints_t *eps, uint32_t max_concurrent_streams,
|
||||
isc_nmsocket_t **sockp);
|
||||
|
||||
isc_nm_http_endpoints_t *
|
||||
isc_nm_http_endpoints_new(isc_mem_t *mctx);
|
||||
/*%<
|
||||
* Create a new, empty HTTP endpoints set object.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'mctx' a valid memory context object.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_nm_http_endpoint(isc_nmsocket_t *sock, const char *uri, isc_nm_recv_cb_t cb,
|
||||
void *cbarg, size_t extrahandlesize);
|
||||
isc_nm_http_endpoints_add(isc_nm_http_endpoints_t *restrict eps,
|
||||
const char *uri, const isc_nm_recv_cb_t cb,
|
||||
void *cbarg, const size_t extrahandlesize);
|
||||
/*%< Adds a new endpoint to the given HTTP endpoints set object.
|
||||
*
|
||||
* NOTE: adding an endpoint is allowed only if the endpoint object has
|
||||
* not been passed to isc_nm_listenhttp() yet.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'eps' is a valid pointer to a valid isc_nm_http_endpoints_t
|
||||
* object;
|
||||
* \li 'uri' is a valid pointer to a string of length > 0;
|
||||
* \li 'cb' is a valid pointer to a read callback function.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_nm_http_endpoints_attach(isc_nm_http_endpoints_t * source,
|
||||
isc_nm_http_endpoints_t **targetp);
|
||||
/*%<
|
||||
* Attaches to an HTTP endpoints set object.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'source' is a non-NULL pointer to a valid
|
||||
* isc_nm_http_endpoints_t object;
|
||||
* \li 'target' is a pointer to a pointer, containing NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_nm_http_endpoints_detach(isc_nm_http_endpoints_t **restrict epsp);
|
||||
/*%<
|
||||
* Detaches from an HTTP endpoints set object. When reference count
|
||||
* reaches 0, the object get deleted.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'epsp' is a pointer to a pointer to a valid
|
||||
* isc_nm_http_endpoints_t object.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc_nm_is_http_handle(isc_nmhandle_t *handle);
|
||||
|
@@ -92,6 +92,11 @@ typedef struct isc_time isc_time_t; /*%< Time */
|
||||
typedef struct isc_timer isc_timer_t; /*%< Timer */
|
||||
typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */
|
||||
|
||||
#if HAVE_LIBNGHTTP2
|
||||
typedef struct isc_nm_http_endpoints isc_nm_http_endpoints_t;
|
||||
/*%< HTTP endpoints set */
|
||||
#endif /* HAVE_LIBNGHTTP2 */
|
||||
|
||||
typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
|
||||
typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int);
|
||||
|
||||
|
@@ -213,6 +213,10 @@ static void
|
||||
server_call_cb(isc_nmsocket_t *socket, isc_nm_http_session_t *session,
|
||||
const isc_result_t result, isc_region_t *data);
|
||||
|
||||
static isc_nm_httphandler_t *
|
||||
http_endpoints_find(const char *request_path,
|
||||
const isc_nm_http_endpoints_t *restrict eps);
|
||||
|
||||
static bool
|
||||
http_session_active(isc_nm_http_session_t *session) {
|
||||
REQUIRE(VALID_HTTP2_SESSION(session));
|
||||
@@ -1653,27 +1657,15 @@ server_on_begin_headers_callback(nghttp2_session *ngsession,
|
||||
|
||||
static isc_nm_httphandler_t *
|
||||
find_server_request_handler(const char *request_path,
|
||||
isc_nmsocket_t *serversocket) {
|
||||
const isc_nmsocket_t *serversocket) {
|
||||
isc_nm_httphandler_t *handler = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(serversocket));
|
||||
|
||||
if (request_path == NULL || *request_path == '\0') {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RWLOCK(&serversocket->h2.lock, isc_rwlocktype_read);
|
||||
if (atomic_load(&serversocket->listening)) {
|
||||
for (handler = ISC_LIST_HEAD(serversocket->h2.handlers);
|
||||
handler != NULL; handler = ISC_LIST_NEXT(handler, link))
|
||||
{
|
||||
if (!strcmp(request_path, handler->path)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
handler = http_endpoints_find(
|
||||
request_path, serversocket->h2.listener_endpoints);
|
||||
}
|
||||
RWUNLOCK(&serversocket->h2.lock, isc_rwlocktype_read);
|
||||
|
||||
return (handler);
|
||||
}
|
||||
|
||||
@@ -2418,10 +2410,15 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
isc_result_t
|
||||
isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
|
||||
isc_quota_t *quota, isc_tlsctx_t *ctx,
|
||||
uint32_t max_concurrent_streams, isc_nmsocket_t **sockp) {
|
||||
isc_nm_http_endpoints_t *eps, uint32_t max_concurrent_streams,
|
||||
isc_nmsocket_t **sockp) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(!ISC_LIST_EMPTY(eps->handlers));
|
||||
REQUIRE(!ISC_LIST_EMPTY(eps->handler_cbargs));
|
||||
REQUIRE(atomic_load(&eps->in_use) == false);
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_httplistener, iface);
|
||||
sock->h2.max_concurrent_streams =
|
||||
@@ -2433,6 +2430,9 @@ isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
|
||||
sock->h2.max_concurrent_streams = max_concurrent_streams;
|
||||
}
|
||||
|
||||
atomic_store(&eps->in_use, true);
|
||||
isc_nm_http_endpoints_attach(eps, &sock->h2.listener_endpoints);
|
||||
|
||||
if (ctx != NULL) {
|
||||
isc_tlsctx_enable_http2server_alpn(ctx);
|
||||
result = isc_nm_listentls(mgr, iface, httplisten_acceptcb, sock,
|
||||
@@ -2462,6 +2462,96 @@ isc_nm_listenhttp(isc_nm_t *mgr, isc_sockaddr_t *iface, int backlog,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_nm_http_endpoints_t *
|
||||
isc_nm_http_endpoints_new(isc_mem_t *mctx) {
|
||||
isc_nm_http_endpoints_t *restrict eps;
|
||||
REQUIRE(mctx != NULL);
|
||||
|
||||
eps = isc_mem_get(mctx, sizeof(*eps));
|
||||
*eps = (isc_nm_http_endpoints_t){ .mctx = NULL };
|
||||
|
||||
isc_mem_attach(mctx, &eps->mctx);
|
||||
ISC_LIST_INIT(eps->handler_cbargs);
|
||||
ISC_LIST_INIT(eps->handlers);
|
||||
isc_refcount_init(&eps->references, 1);
|
||||
atomic_init(&eps->in_use, false);
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
void
|
||||
isc_nm_http_endpoints_detach(isc_nm_http_endpoints_t **restrict epsp) {
|
||||
isc_nm_http_endpoints_t *restrict eps;
|
||||
isc_mem_t *mctx;
|
||||
isc_nm_httphandler_t *handler = NULL;
|
||||
isc_nm_httpcbarg_t *httpcbarg = NULL;
|
||||
|
||||
REQUIRE(epsp != NULL);
|
||||
eps = *epsp;
|
||||
REQUIRE(eps != NULL);
|
||||
|
||||
if (isc_refcount_decrement(&eps->references) > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
mctx = eps->mctx;
|
||||
|
||||
/* Delete all handlers */
|
||||
handler = ISC_LIST_HEAD(eps->handlers);
|
||||
while (handler != NULL) {
|
||||
isc_nm_httphandler_t *next = NULL;
|
||||
|
||||
next = ISC_LIST_NEXT(handler, link);
|
||||
ISC_LIST_DEQUEUE(eps->handlers, handler, link);
|
||||
isc_mem_free(mctx, handler->path);
|
||||
isc_mem_put(mctx, handler, sizeof(*handler));
|
||||
handler = next;
|
||||
}
|
||||
|
||||
httpcbarg = ISC_LIST_HEAD(eps->handler_cbargs);
|
||||
while (httpcbarg != NULL) {
|
||||
isc_nm_httpcbarg_t *next = NULL;
|
||||
|
||||
next = ISC_LIST_NEXT(httpcbarg, link);
|
||||
ISC_LIST_DEQUEUE(eps->handler_cbargs, httpcbarg, link);
|
||||
isc_mem_put(mctx, httpcbarg, sizeof(isc_nm_httpcbarg_t));
|
||||
httpcbarg = next;
|
||||
}
|
||||
|
||||
isc_mem_putanddetach(&mctx, eps, sizeof(*eps));
|
||||
*epsp = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
isc_nm_http_endpoints_attach(isc_nm_http_endpoints_t *source,
|
||||
isc_nm_http_endpoints_t **targetp) {
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
static isc_nm_httphandler_t *
|
||||
http_endpoints_find(const char *request_path,
|
||||
const isc_nm_http_endpoints_t *restrict eps) {
|
||||
isc_nm_httphandler_t *handler = NULL;
|
||||
|
||||
if (request_path == NULL || *request_path == '\0') {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (handler = ISC_LIST_HEAD(eps->handlers); handler != NULL;
|
||||
handler = ISC_LIST_NEXT(handler, link))
|
||||
{
|
||||
if (!strcmp(request_path, handler->path)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (handler);
|
||||
}
|
||||
|
||||
/*
|
||||
* In DoH we just need to intercept the request - the response can be sent
|
||||
* to the client code via the nmhandle directly as it's always just the
|
||||
@@ -2484,40 +2574,41 @@ http_callback(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *data,
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_http_endpoint(isc_nmsocket_t *sock, const char *uri, isc_nm_recv_cb_t cb,
|
||||
void *cbarg, size_t extrahandlesize) {
|
||||
isc_nm_httphandler_t *handler = NULL;
|
||||
isc_nm_httpcbarg_t *httpcbarg = NULL;
|
||||
isc_nm_http_endpoints_add(isc_nm_http_endpoints_t *restrict eps,
|
||||
const char *uri, const isc_nm_recv_cb_t cb,
|
||||
void *cbarg, const size_t extrahandlesize) {
|
||||
isc_mem_t *mctx;
|
||||
isc_nm_httphandler_t *restrict handler = NULL;
|
||||
isc_nm_httpcbarg_t *restrict httpcbarg = NULL;
|
||||
bool newhandler = false;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_httplistener);
|
||||
REQUIRE(eps != NULL);
|
||||
REQUIRE(isc_nm_http_path_isvalid(uri));
|
||||
REQUIRE(atomic_load(&eps->in_use) == false);
|
||||
|
||||
httpcbarg = isc_mem_get(sock->mgr->mctx, sizeof(isc_nm_httpcbarg_t));
|
||||
mctx = eps->mctx;
|
||||
|
||||
httpcbarg = isc_mem_get(mctx, sizeof(isc_nm_httpcbarg_t));
|
||||
*httpcbarg = (isc_nm_httpcbarg_t){ .cb = cb, .cbarg = cbarg };
|
||||
ISC_LINK_INIT(httpcbarg, link);
|
||||
|
||||
if (find_server_request_handler(uri, sock) == NULL) {
|
||||
handler = isc_mem_get(sock->mgr->mctx, sizeof(*handler));
|
||||
if (http_endpoints_find(uri, eps) == NULL) {
|
||||
handler = isc_mem_get(mctx, sizeof(*handler));
|
||||
*handler = (isc_nm_httphandler_t){
|
||||
.cb = http_callback,
|
||||
.cbarg = httpcbarg,
|
||||
.extrahandlesize = extrahandlesize,
|
||||
.path = isc_mem_strdup(sock->mgr->mctx, uri)
|
||||
.path = isc_mem_strdup(mctx, uri)
|
||||
};
|
||||
ISC_LINK_INIT(handler, link);
|
||||
|
||||
newhandler = true;
|
||||
}
|
||||
|
||||
RWLOCK(&sock->h2.lock, isc_rwlocktype_write);
|
||||
if (newhandler) {
|
||||
ISC_LIST_APPEND(sock->h2.handlers, handler, link);
|
||||
ISC_LIST_APPEND(eps->handlers, handler, link);
|
||||
}
|
||||
ISC_LIST_APPEND(sock->h2.handler_cbargs, httpcbarg, link);
|
||||
RWUNLOCK(&sock->h2.lock, isc_rwlocktype_write);
|
||||
|
||||
ISC_LIST_APPEND(eps->handler_cbargs, httpcbarg, link);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -2544,37 +2635,6 @@ isc__nm_http_stoplistening(isc_nmsocket_t *sock) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_handlers(isc_nmsocket_t *sock) {
|
||||
isc_nm_httphandler_t *handler = NULL;
|
||||
isc_nm_httpcbarg_t *httpcbarg = NULL;
|
||||
|
||||
/* Delete all handlers */
|
||||
RWLOCK(&sock->h2.lock, isc_rwlocktype_write);
|
||||
handler = ISC_LIST_HEAD(sock->h2.handlers);
|
||||
while (handler != NULL) {
|
||||
isc_nm_httphandler_t *next = NULL;
|
||||
|
||||
next = ISC_LIST_NEXT(handler, link);
|
||||
ISC_LIST_DEQUEUE(sock->h2.handlers, handler, link);
|
||||
isc_mem_free(sock->mgr->mctx, handler->path);
|
||||
isc_mem_put(sock->mgr->mctx, handler, sizeof(*handler));
|
||||
handler = next;
|
||||
}
|
||||
|
||||
httpcbarg = ISC_LIST_HEAD(sock->h2.handler_cbargs);
|
||||
while (httpcbarg != NULL) {
|
||||
isc_nm_httpcbarg_t *next = NULL;
|
||||
|
||||
next = ISC_LIST_NEXT(httpcbarg, link);
|
||||
ISC_LIST_DEQUEUE(sock->h2.handler_cbargs, httpcbarg, link);
|
||||
isc_mem_put(sock->mgr->mctx, httpcbarg,
|
||||
sizeof(isc_nm_httpcbarg_t));
|
||||
httpcbarg = next;
|
||||
}
|
||||
RWUNLOCK(&sock->h2.lock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_httpstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_httpstop_t *ievent = (isc__netievent_httpstop_t *)ev0;
|
||||
@@ -2903,12 +2963,6 @@ isc__nm_http_initsocket(isc_nmsocket_t *sock) {
|
||||
.request_type = ISC_HTTP_REQ_UNSUPPORTED,
|
||||
.request_scheme = ISC_HTTP_SCHEME_UNSUPPORTED,
|
||||
};
|
||||
|
||||
if (sock->type == isc_nm_httplistener) {
|
||||
ISC_LIST_INIT(sock->h2.handlers);
|
||||
ISC_LIST_INIT(sock->h2.handler_cbargs);
|
||||
isc_rwlock_init(&sock->h2.lock, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2922,9 +2976,11 @@ isc__nm_http_cleanup_data(isc_nmsocket_t *sock) {
|
||||
|
||||
if (sock->type == isc_nm_httplistener ||
|
||||
sock->type == isc_nm_httpsocket) {
|
||||
if (sock->type == isc_nm_httplistener) {
|
||||
clear_handlers(sock);
|
||||
isc_rwlock_destroy(&sock->h2.lock);
|
||||
if (sock->type == isc_nm_httplistener &&
|
||||
sock->h2.listener_endpoints != NULL) {
|
||||
/* Delete all handlers */
|
||||
isc_nm_http_endpoints_detach(
|
||||
&sock->h2.listener_endpoints);
|
||||
}
|
||||
|
||||
if (sock->h2.request_path != NULL) {
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/thread.h>
|
||||
@@ -315,15 +314,6 @@ typedef union {
|
||||
isc_nm_accept_cb_t accept;
|
||||
} isc__nm_cb_t;
|
||||
|
||||
typedef struct isc_nm_httphandler isc_nm_httphandler_t;
|
||||
struct isc_nm_httphandler {
|
||||
char *path;
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
size_t extrahandlesize;
|
||||
LINK(isc_nm_httphandler_t) link;
|
||||
};
|
||||
|
||||
/*
|
||||
* Wrapper around uv_req_t with 'our' fields in it. req->data should
|
||||
* always point to its parent. Note that we always allocate more than
|
||||
@@ -756,6 +746,7 @@ enum {
|
||||
STATID_ACTIVE = 10
|
||||
};
|
||||
|
||||
#if HAVE_LIBNGHTTP2
|
||||
typedef struct isc_nmsocket_tls_send_req {
|
||||
isc_nmsocket_t *tlssock;
|
||||
isc_region_t data;
|
||||
@@ -783,6 +774,24 @@ typedef struct isc_nm_httpcbarg {
|
||||
LINK(struct isc_nm_httpcbarg) link;
|
||||
} isc_nm_httpcbarg_t;
|
||||
|
||||
typedef struct isc_nm_httphandler {
|
||||
char *path;
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
size_t extrahandlesize;
|
||||
LINK(struct isc_nm_httphandler) link;
|
||||
} isc_nm_httphandler_t;
|
||||
|
||||
struct isc_nm_http_endpoints {
|
||||
isc_mem_t *mctx;
|
||||
|
||||
ISC_LIST(isc_nm_httphandler_t) handlers;
|
||||
ISC_LIST(isc_nm_httpcbarg_t) handler_cbargs;
|
||||
|
||||
isc_refcount_t references;
|
||||
atomic_bool in_use;
|
||||
};
|
||||
|
||||
typedef struct isc_nmsocket_h2 {
|
||||
isc_nmsocket_t *psock; /* owner of the structure */
|
||||
char *request_path;
|
||||
@@ -816,9 +825,7 @@ typedef struct isc_nmsocket_h2 {
|
||||
void *cbarg;
|
||||
LINK(struct isc_nmsocket_h2) link;
|
||||
|
||||
ISC_LIST(isc_nm_httphandler_t) handlers;
|
||||
ISC_LIST(isc_nm_httpcbarg_t) handler_cbargs;
|
||||
isc_rwlock_t lock;
|
||||
isc_nm_http_endpoints_t *listener_endpoints;
|
||||
|
||||
bool response_submitted;
|
||||
struct {
|
||||
@@ -829,6 +836,7 @@ typedef struct isc_nmsocket_h2 {
|
||||
void *cstream;
|
||||
} connect;
|
||||
} isc_nmsocket_h2_t;
|
||||
#endif /* HAVE_LIBNGHTTP2 */
|
||||
|
||||
typedef void (*isc_nm_closehandlecb_t)(void *arg);
|
||||
/*%<
|
||||
@@ -875,6 +883,7 @@ struct isc_nmsocket {
|
||||
isc__nm_uvreq_t *pending_req;
|
||||
} tls;
|
||||
|
||||
#if HAVE_LIBNGHTTP2
|
||||
/*% TLS stuff */
|
||||
struct tlsstream {
|
||||
bool server;
|
||||
@@ -895,6 +904,7 @@ struct isc_nmsocket {
|
||||
} tlsstream;
|
||||
|
||||
isc_nmsocket_h2_t h2;
|
||||
#endif /* HAVE_LIBNGHTTP2 */
|
||||
/*%
|
||||
* quota is the TCP client, attached when a TCP connection
|
||||
* is established. pquota is a non-attached pointer to the
|
||||
|
@@ -1515,7 +1515,9 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
|
||||
isc_condition_init(&sock->scond);
|
||||
isc_refcount_init(&sock->references, 1);
|
||||
|
||||
#if HAVE_LIBNGHTTP2
|
||||
memset(&sock->tlsstream, 0, sizeof(sock->tlsstream));
|
||||
#endif /* HAVE_LIBNGHTTP2 */
|
||||
|
||||
NETMGR_TRACE_LOG("isc__nmsocket_init():%p->references = %" PRIuFAST32
|
||||
"\n",
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#if HAVE_CMOCKA
|
||||
#if defined(HAVE_CMOCKA) && defined(HAVE_LIBNGHTTP2)
|
||||
#include <inttypes.h>
|
||||
#include <sched.h> /* IWYU pragma: keep */
|
||||
#include <setjmp.h>
|
||||
@@ -83,6 +83,8 @@ static isc_tlsctx_t *client_tlsctx = NULL;
|
||||
static isc_quota_t listener_quota;
|
||||
static atomic_bool check_listener_quota = ATOMIC_VAR_INIT(false);
|
||||
|
||||
static isc_nm_http_endpoints_t *endpoints = NULL;
|
||||
|
||||
/* Timeout for soft-timeout tests (0.05 seconds) */
|
||||
#define T_SOFT 50
|
||||
|
||||
@@ -336,6 +338,9 @@ nm_setup(void **state) {
|
||||
isc_quota_init(&listener_quota, 0);
|
||||
atomic_store(&check_listener_quota, false);
|
||||
|
||||
INSIST(endpoints == NULL);
|
||||
endpoints = isc_nm_http_endpoints_new(test_mctx);
|
||||
|
||||
*state = nm;
|
||||
|
||||
return (0);
|
||||
@@ -360,6 +365,8 @@ nm_teardown(void **state) {
|
||||
|
||||
isc_quota_destroy(&listener_quota);
|
||||
|
||||
isc_nm_http_endpoints_detach(&endpoints);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -483,8 +490,11 @@ mock_doh_uv_tcp_bind(void **state) {
|
||||
|
||||
WILL_RETURN(uv_tcp_bind, UV_EADDRINUSE);
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH, noop_read_cb,
|
||||
NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
|
||||
0, &listen_sock);
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_not_equal(result, ISC_R_SUCCESS);
|
||||
assert_null(listen_sock);
|
||||
|
||||
@@ -500,11 +510,13 @@ doh_noop(void **state) {
|
||||
isc_nmsocket_t *listen_sock = NULL;
|
||||
char req_url[256];
|
||||
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
|
||||
0, &listen_sock);
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH, noop_read_cb,
|
||||
NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH, noop_read_cb, NULL,
|
||||
0);
|
||||
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
@@ -546,12 +558,12 @@ doh_noresponse(void **state) {
|
||||
isc_nmsocket_t *listen_sock = NULL;
|
||||
char req_url[256];
|
||||
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
|
||||
0, &listen_sock);
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH, noop_read_cb,
|
||||
NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH, noop_read_cb, NULL,
|
||||
0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
sockaddr_to_url(&tcp_listen_addr, false, req_url, sizeof(req_url),
|
||||
@@ -647,8 +659,12 @@ doh_timeout_recovery(void **state) {
|
||||
isc_tlsctx_t *ctx = atomic_load(&use_TLS) ? server_tlsctx : NULL;
|
||||
char req_url[256];
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, NULL, NULL,
|
||||
0, &listen_sock);
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
@@ -656,9 +672,6 @@ doh_timeout_recovery(void **state) {
|
||||
* reads to time out.
|
||||
*/
|
||||
noanswer = true;
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Shorten all the TCP client timeouts to 0.05 seconds.
|
||||
@@ -777,13 +790,14 @@ doh_recv_one(void **state) {
|
||||
atomic_store(&total_sends, 1);
|
||||
|
||||
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,
|
||||
0, &listen_sock);
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url,
|
||||
@@ -927,13 +941,14 @@ doh_recv_two(void **state) {
|
||||
atomic_store(&total_sends, 2);
|
||||
|
||||
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,
|
||||
0, &listen_sock);
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url,
|
||||
@@ -1047,13 +1062,13 @@ doh_recv_send(void **state) {
|
||||
isc_thread_t threads[32] = { 0 };
|
||||
isc_quota_t *quotap = init_listener_quota(workers);
|
||||
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
0, &listen_sock);
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
@@ -1151,13 +1166,14 @@ doh_recv_half_send(void **state) {
|
||||
atomic_store(&total_sends, atomic_load(&total_sends) / 2);
|
||||
|
||||
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,
|
||||
0, &listen_sock);
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
@@ -1260,13 +1276,14 @@ doh_half_recv_send(void **state) {
|
||||
atomic_store(&total_sends, atomic_load(&total_sends) / 2);
|
||||
|
||||
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,
|
||||
0, &listen_sock);
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
@@ -1369,13 +1386,14 @@ doh_half_recv_half_send(void **state) {
|
||||
atomic_store(&total_sends, atomic_load(&total_sends) / 2);
|
||||
|
||||
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,
|
||||
0, &listen_sock);
|
||||
|
||||
result = isc_nm_http_endpoints_add(endpoints, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_http_endpoint(listen_sock, DOH_PATH,
|
||||
doh_receive_request_cb, NULL, 0);
|
||||
result = isc_nm_listenhttp(listen_nm, &tcp_listen_addr, 0, quotap,
|
||||
atomic_load(&use_TLS) ? server_tlsctx : NULL,
|
||||
endpoints, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
@@ -2174,7 +2192,11 @@ main(void) {
|
||||
|
||||
int
|
||||
main(void) {
|
||||
#if HAVE_LIBNGHTTP2
|
||||
printf("1..0 # Skipped: cmocka not available\n");
|
||||
#else
|
||||
printf("1..0 # Skipped: libnghttp2 is not available\n");
|
||||
#endif
|
||||
return (SKIPPED_TEST_EXIT_CODE);
|
||||
}
|
||||
|
||||
|
@@ -542,25 +542,29 @@ ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps,
|
||||
size_t neps, isc_quota_t *quota,
|
||||
uint32_t max_concurrent_streams) {
|
||||
#if HAVE_LIBNGHTTP2
|
||||
isc_result_t result;
|
||||
isc_result_t result = ISC_R_FAILURE;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_nm_http_endpoints_t *epset = NULL;
|
||||
|
||||
result = isc_nm_listenhttp(ifp->mgr->nm, &ifp->addr, ifp->mgr->backlog,
|
||||
quota, sslctx, max_concurrent_streams,
|
||||
&sock);
|
||||
epset = isc_nm_http_endpoints_new(ifp->mgr->mctx);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
for (size_t i = 0; i < neps; i++) {
|
||||
INSIST(isc_nm_http_path_isvalid(eps[i]));
|
||||
result = isc_nm_http_endpoint(sock, eps[i],
|
||||
ns__client_request, ifp,
|
||||
sizeof(ns_client_t));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
for (size_t i = 0; i < neps; i++) {
|
||||
result = isc_nm_http_endpoints_add(epset, eps[i],
|
||||
ns__client_request, ifp,
|
||||
sizeof(ns_client_t));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = isc_nm_listenhttp(
|
||||
ifp->mgr->nm, &ifp->addr, ifp->mgr->backlog, quota,
|
||||
sslctx, epset, max_concurrent_streams, &sock);
|
||||
}
|
||||
|
||||
isc_nm_http_endpoints_detach(&epset);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
|
||||
"creating %s socket: %s",
|
||||
|
Reference in New Issue
Block a user