nonfunctional checkpoint: introduce isc_nm_dnspair()
This commit is contained in:
@@ -499,9 +499,11 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
* 'cb'.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_nm_dnspair(isc_nm_t *mgr, isc_nm_cb_t ccb, void *ccbarg,
|
||||
isc_nm_recv_cb_t scb, void *scbarg);
|
||||
/*%<
|
||||
* Returns 'true' iff 'handle' is associated with a socket of type
|
||||
* 'isc_nm_tlsdnssocket'.
|
||||
* FIXME
|
||||
*/
|
||||
|
||||
bool
|
||||
|
||||
@@ -295,6 +295,8 @@ typedef enum isc__netievent_type {
|
||||
netievent_tcpdnsread,
|
||||
netievent_tcpdnscancel,
|
||||
|
||||
netievent_dnspair,
|
||||
|
||||
netievent_tlsclose,
|
||||
netievent_tlssend,
|
||||
netievent_tlsstartread,
|
||||
@@ -1573,6 +1575,12 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
* Callback handlers for asynchronous TCPDNS events.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_async_dnspair(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
/*%<
|
||||
* Callback handlers for asynchronous DNS socket pair events.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
|
||||
/*
|
||||
@@ -1956,6 +1964,8 @@ NETIEVENT_SOCKET_REQ_TYPE(tcpdnssend);
|
||||
NETIEVENT_SOCKET_HANDLE_TYPE(tcpdnscancel);
|
||||
NETIEVENT_SOCKET_QUOTA_TYPE(tcpdnsaccept);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_TYPE(dnspair);
|
||||
|
||||
NETIEVENT_SOCKET_TYPE(tlsdnsclose);
|
||||
NETIEVENT_SOCKET_TYPE(tlsdnsread);
|
||||
NETIEVENT_SOCKET_TYPE(tlsdnsstop);
|
||||
@@ -2026,6 +2036,8 @@ NETIEVENT_SOCKET_REQ_DECL(tcpdnssend);
|
||||
NETIEVENT_SOCKET_HANDLE_DECL(tcpdnscancel);
|
||||
NETIEVENT_SOCKET_QUOTA_DECL(tcpdnsaccept);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_DECL(dnspair);
|
||||
|
||||
NETIEVENT_SOCKET_DECL(tlsdnsclose);
|
||||
NETIEVENT_SOCKET_DECL(tlsdnsread);
|
||||
NETIEVENT_SOCKET_DECL(tlsdnsstop);
|
||||
|
||||
@@ -900,6 +900,8 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
|
||||
NETIEVENT_CASE(tcpdnsread);
|
||||
NETIEVENT_CASE(tcpdnsstop);
|
||||
|
||||
NETIEVENT_CASE(dnspair);
|
||||
|
||||
NETIEVENT_CASE(tlsdnscycle);
|
||||
NETIEVENT_CASE(tlsdnsaccept);
|
||||
NETIEVENT_CASE(tlsdnslisten);
|
||||
@@ -1023,6 +1025,8 @@ NETIEVENT_SOCKET_REQ_DEF(tcpdnssend);
|
||||
NETIEVENT_SOCKET_HANDLE_DEF(tcpdnscancel);
|
||||
NETIEVENT_SOCKET_QUOTA_DEF(tcpdnsaccept);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_DEF(dnspair);
|
||||
|
||||
NETIEVENT_SOCKET_DEF(tlsdnsclose);
|
||||
NETIEVENT_SOCKET_DEF(tlsdnsread);
|
||||
NETIEVENT_SOCKET_DEF(tlsdnsstop);
|
||||
|
||||
+127
-1
@@ -387,6 +387,7 @@ start_tcpdns_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock,
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_listentcpdns(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
|
||||
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
|
||||
@@ -701,7 +702,8 @@ isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
* This MUST be done asynchronously, no matter which thread we're
|
||||
* in. The callback function for isc_nm_read() often calls
|
||||
* isc_nm_read() again; if we tried to do that synchronously
|
||||
* we'd clash in processbuffer() and grow the stack indefinitely.
|
||||
* we'd clash in isc__nm_tcpdns_processbuffer() and grow the
|
||||
* stack indefinitely.
|
||||
*/
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
@@ -1460,3 +1462,127 @@ isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF, false);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
pairdns_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
atomic_store(&sock->connected, true);
|
||||
|
||||
error:
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
SIGNAL(&sock->cond);
|
||||
if (!atomic_load(&sock->active)) {
|
||||
WAIT(&sock->scond, &sock->lock);
|
||||
}
|
||||
INSIST(atomic_load(&sock->active));
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_dnspair(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_dnspair_t *ievent =
|
||||
(isc__netievent_dnspair_t *)ev0;
|
||||
isc_nmsocket_t *sock = ievent->sock;
|
||||
isc__nm_uvreq_t *req = ievent->req;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
UNUSED(worker);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
REQUIRE(sock->parent == NULL);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
result = pairdns_direct(sock, req);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_tcpdns_close(sock);
|
||||
}
|
||||
|
||||
/*
|
||||
* The sock is now attached to the handle.
|
||||
*/
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_nm_dnspair(isc_nm_t *mgr, isc_nm_cb_t ccb, void *ccbarg,
|
||||
isc_nm_recv_cb_t scb, void *scbarg) {
|
||||
uv_os_sock_t fds[2];
|
||||
isc_nmsocket_t *csock = NULL, *ssock = NULL;
|
||||
isc__netievent_tcpdnsconnect_t *cevent = NULL;
|
||||
isc__netievent_tcpdnslisten_t *sevent = NULL;
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
int r;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
/* XXX: uv_socketpair() was introduced in libuv 1.40 */
|
||||
r = socketpair(PF_LOCAL, SOCK_STREAM, 0, fds);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
|
||||
/* Set up server socket */
|
||||
ssock = isc_mem_get(mgr->mctx, sizeof(*ssock));
|
||||
isc__nmsocket_init(ssock, mgr, isc_nm_tcpdnssocket, NULL);
|
||||
ssock->recv_cb = scb;
|
||||
ssock->recv_cbarg = scbarg;
|
||||
ssock->fd = fds[1];
|
||||
|
||||
sevent = isc__nm_get_netievent_tcpdnslisten(mgr, ssock);
|
||||
|
||||
/* Set up client socket */
|
||||
csock = isc_mem_get(mgr->mctx, sizeof(*csock));
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tcpdnssocket, NULL);
|
||||
csock->result = ISC_R_UNSET;
|
||||
csock->fd = fds[0];
|
||||
atomic_init(&csock->client, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, csock);
|
||||
req->cb.connect = ccb;
|
||||
req->cbarg = ccbarg;
|
||||
req->handle = isc__nmhandle_get(csock, NULL, NULL);
|
||||
|
||||
cevent = isc__nm_get_netievent_dnspair(mgr, csock, req);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
atomic_store(&csock->active, true);
|
||||
csock->tid = isc_nm_tid();
|
||||
isc__nm_async_dnspair(&mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)cevent);
|
||||
isc__nm_put_netievent_dnspair(mgr, cevent);
|
||||
} else {
|
||||
atomic_init(&csock->active, false);
|
||||
csock->tid = isc_random_uniform(mgr->nworkers);
|
||||
isc__nm_enqueue_ievent(&mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)cevent);
|
||||
}
|
||||
|
||||
ssock->tid = isc_random_uniform(mgr->nworkers);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[ssock->tid],
|
||||
(isc__netievent_t *)sevent);
|
||||
|
||||
LOCK(&csock->lock);
|
||||
while (csock->result == ISC_R_UNSET) {
|
||||
WAIT(&csock->cond, &csock->lock);
|
||||
}
|
||||
atomic_store(&csock->active, true);
|
||||
BROADCAST(&csock->scond);
|
||||
UNLOCK(&csock->lock);
|
||||
}
|
||||
|
||||
@@ -898,8 +898,8 @@ isc__nm_tlsdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
* This MUST be done asynchronously, no matter which thread
|
||||
* we're in. The callback function for isc_nm_read() often calls
|
||||
* isc_nm_read() again; if we tried to do that synchronously
|
||||
* we'd clash in processbuffer() and grow the stack
|
||||
* indefinitely.
|
||||
* we'd clash in isc__nm_tlsdns_processbuffer() and grow the
|
||||
* stack indefinitely.
|
||||
*/
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
|
||||
Reference in New Issue
Block a user