mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 02:32:03 -04:00
isc_nm_*connect() always return via callback
The isc_nm_*connect() functions were refactored to always return the connection status via the connect callback instead of sometimes returning the hard failure directly (for example, when the socket could not be created, or when the network manager was shutting down). This commit changes the connect functions in all the network manager modules, and also makes the necessary refactoring changes in places where the connect functions are called.
This commit is contained in:
parent
a70cd026df
commit
86f4872dd6
15 changed files with 349 additions and 556 deletions
|
|
@ -574,7 +574,6 @@ rndc_connected(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
|
||||
static void
|
||||
rndc_startconnect(isc_sockaddr_t *addr) {
|
||||
isc_result_t result;
|
||||
char socktext[ISC_SOCKADDR_FORMATSIZE];
|
||||
isc_sockaddr_t *local = NULL;
|
||||
|
||||
|
|
@ -600,10 +599,8 @@ rndc_startconnect(isc_sockaddr_t *addr) {
|
|||
}
|
||||
|
||||
atomic_fetch_add_relaxed(&connects, 1);
|
||||
DO("create connection",
|
||||
isc_nm_tcpconnect(netmgr, (isc_nmiface_t *)local,
|
||||
(isc_nmiface_t *)addr, rndc_connected, &rndc_ccmsg,
|
||||
10000, 0));
|
||||
isc_nm_tcpconnect(netmgr, (isc_nmiface_t *)local, (isc_nmiface_t *)addr,
|
||||
rndc_connected, &rndc_ccmsg, 10000, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -235,8 +235,6 @@ parse_options(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
INSIST(optind < argc);
|
||||
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = family,
|
||||
|
|
@ -281,7 +279,7 @@ parse_options(int argc, char **argv) {
|
|||
|
||||
isc_sockaddr_format(&sockaddr_remote, buf, sizeof(buf));
|
||||
|
||||
printf("to %s, %d workers\n", buf, workers);
|
||||
printf(" to %s, %d workers\n", buf, workers);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -378,16 +376,16 @@ connect_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
|
|||
isc_nmhandle_t *readhandle = NULL;
|
||||
|
||||
REQUIRE(handle != NULL);
|
||||
REQUIRE(eresult == ISC_R_SUCCESS);
|
||||
UNUSED(cbarg);
|
||||
|
||||
fprintf(stderr, "ECHO_CLIENT:%s:%s\n", __func__,
|
||||
isc_result_totext(eresult));
|
||||
|
||||
if (eresult != ISC_R_SUCCESS) {
|
||||
kill(getpid(), SIGTERM);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "ECHO_CLIENT:%s\n", __func__);
|
||||
|
||||
isc_nmhandle_attach(handle, &readhandle);
|
||||
isc_nm_read(handle, read_cb, readhandle);
|
||||
isc_nm_send(handle, &message, send_cb, NULL);
|
||||
|
|
@ -422,28 +420,23 @@ sockaddr_to_url(isc_sockaddr_t *sa, const bool https, char *outbuf,
|
|||
|
||||
static void
|
||||
run(void) {
|
||||
isc_result_t result;
|
||||
|
||||
switch (protocol) {
|
||||
case UDP:
|
||||
result = isc_nm_udpconnect(netmgr,
|
||||
(isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote,
|
||||
connect_cb, NULL, timeout, 0);
|
||||
isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote, connect_cb,
|
||||
NULL, timeout, 0);
|
||||
break;
|
||||
case TCP:
|
||||
result = isc_nm_tcpdnsconnect(netmgr,
|
||||
(isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote,
|
||||
connect_cb, NULL, timeout, 0);
|
||||
isc_nm_tcpdnsconnect(netmgr, (isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote,
|
||||
connect_cb, NULL, timeout, 0);
|
||||
break;
|
||||
case DOT: {
|
||||
isc_tlsctx_createclient(&tls_ctx);
|
||||
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
netmgr, (isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote, connect_cb, NULL,
|
||||
timeout, 0, tls_ctx);
|
||||
isc_nm_tlsdnsconnect(netmgr, (isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote,
|
||||
connect_cb, NULL, timeout, 0, tls_ctx);
|
||||
break;
|
||||
}
|
||||
case HTTP_GET:
|
||||
|
|
@ -460,16 +453,15 @@ run(void) {
|
|||
if (is_https) {
|
||||
isc_tlsctx_createclient(&tls_ctx);
|
||||
}
|
||||
result = isc_nm_httpconnect(
|
||||
netmgr, (isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote, req_url, is_post,
|
||||
connect_cb, NULL, tls_ctx, timeout, 0);
|
||||
isc_nm_httpconnect(netmgr, (isc_nmiface_t *)&sockaddr_local,
|
||||
(isc_nmiface_t *)&sockaddr_remote, req_url,
|
||||
is_post, connect_cb, NULL, tls_ctx, timeout,
|
||||
0);
|
||||
} break;
|
||||
default:
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
REQUIRE(result == ISC_R_SUCCESS);
|
||||
|
||||
waitforsignal();
|
||||
|
||||
|
|
|
|||
|
|
@ -894,17 +894,17 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
|
|||
*/
|
||||
switch (transport_type) {
|
||||
case DNS_TRANSPORT_TCP:
|
||||
CHECK(isc_nm_tcpdnsconnect(
|
||||
xfr->netmgr, (isc_nmiface_t *)&xfr->sourceaddr,
|
||||
(isc_nmiface_t *)&xfr->masteraddr, xfrin_connect_done,
|
||||
connect_xfr, 30000, 0));
|
||||
isc_nm_tcpdnsconnect(xfr->netmgr,
|
||||
(isc_nmiface_t *)&xfr->sourceaddr,
|
||||
(isc_nmiface_t *)&xfr->masteraddr,
|
||||
xfrin_connect_done, connect_xfr, 30000, 0);
|
||||
break;
|
||||
case DNS_TRANSPORT_TLS:
|
||||
CHECK(isc_tlsctx_createclient(&xfr->tlsctx));
|
||||
CHECK(isc_nm_tlsdnsconnect(
|
||||
isc_nm_tlsdnsconnect(
|
||||
xfr->netmgr, (isc_nmiface_t *)&xfr->sourceaddr,
|
||||
(isc_nmiface_t *)&xfr->masteraddr, xfrin_connect_done,
|
||||
connect_xfr, 30000, 0, xfr->tlsctx));
|
||||
connect_xfr, 30000, 0, xfr->tlsctx);
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
* can then be freed automatically when the handle is destroyed.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize);
|
||||
|
|
@ -318,7 +318,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
*
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize);
|
||||
|
|
@ -481,16 +481,16 @@ isc_nm_listentls(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
size_t extrahandlesize, int backlog, isc_quota_t *quota,
|
||||
isc_tlsctx_t *sslctx, isc_nmsocket_t **sockp);
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tlsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, isc_tlsctx_t *ctx,
|
||||
unsigned int timeout, size_t extrahandlesize);
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize);
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize, isc_tlsctx_t *sslctx);
|
||||
|
|
@ -508,7 +508,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
* 'cb'.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
const char *uri, bool POST, isc_nm_cb_t cb, void *cbarg,
|
||||
isc_tlsctx_t *ctx, unsigned int timeout,
|
||||
|
|
|
|||
|
|
@ -1147,12 +1147,11 @@ error:
|
|||
isc__nmsocket_detach(&http_sock);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
const char *uri, bool post, isc_nm_cb_t cb, void *cbarg,
|
||||
isc_tlsctx_t *tlsctx, unsigned int timeout,
|
||||
size_t extrahandlesize) {
|
||||
isc_result_t result;
|
||||
isc_nmiface_t local_interface;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
|
||||
|
|
@ -1176,12 +1175,34 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
sock->result = ISC_R_DEFAULT;
|
||||
sock->connect_cb = cb;
|
||||
sock->connect_cbarg = cbarg;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
isc__nm_uvreq_t *req = isc__nm_uvreq_get(mgr, sock);
|
||||
|
||||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
req->peer = peer->addr;
|
||||
req->local = local->addr;
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer,
|
||||
&sock->iface->addr);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
}
|
||||
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, ISC_R_CANCELED, true);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
isc__nmsocket_detach(&sock);
|
||||
return;
|
||||
}
|
||||
|
||||
sock->h2 = (isc_nmsocket_h2_t){ .connect.uri = isc_mem_strdup(mgr->mctx,
|
||||
uri),
|
||||
.connect.post = post,
|
||||
.connect.tlsctx = tlsctx };
|
||||
ISC_LINK_INIT(&sock->h2, link);
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
/*
|
||||
* We need to prevent the interface object data from going out of
|
||||
|
|
@ -1193,16 +1214,12 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
}
|
||||
|
||||
if (tlsctx != NULL) {
|
||||
result = isc_nm_tlsconnect(mgr, local, peer,
|
||||
transport_connect_cb, sock, tlsctx,
|
||||
timeout, 0);
|
||||
isc_nm_tlsconnect(mgr, local, peer, transport_connect_cb, sock,
|
||||
tlsctx, timeout, 0);
|
||||
} else {
|
||||
result = isc_nm_tcpconnect(mgr, local, peer,
|
||||
transport_connect_cb, sock, timeout,
|
||||
0);
|
||||
isc_nm_tcpconnect(mgr, local, peer, transport_connect_cb, sock,
|
||||
timeout, 0);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
|
|||
|
|
@ -1871,7 +1871,7 @@ isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
|
|||
}
|
||||
|
||||
worker = &sock->mgr->workers[sock->tid];
|
||||
INSIST(!worker->recvbuf_inuse);
|
||||
INSIST(!worker->recvbuf_inuse || sock->type == isc_nm_udpsocket);
|
||||
|
||||
buf->base = worker->recvbuf;
|
||||
buf->len = size;
|
||||
|
|
@ -2335,12 +2335,13 @@ isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
|||
.req = uvreq,
|
||||
.result = eresult };
|
||||
isc__nm_async_connectcb(NULL, (isc__netievent_t *)&ievent);
|
||||
return;
|
||||
} else {
|
||||
isc__netievent_connectcb_t *ievent =
|
||||
isc__nm_get_netievent_connectcb(sock->mgr, sock, uvreq,
|
||||
eresult);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
isc__netievent_connectcb_t *ievent = isc__nm_get_netievent_connectcb(
|
||||
sock->mgr, sock, uvreq, eresult);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -141,11 +141,6 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
RUNTIME_CHECK(r == 0);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
|
||||
if (r != 0) {
|
||||
isc__nm_closesocket(sock->fd);
|
||||
|
|
@ -180,7 +175,6 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
|
||||
done:
|
||||
result = isc__nm_uverr2result(r);
|
||||
error:
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
SIGNAL(&sock->cond);
|
||||
|
|
@ -215,7 +209,7 @@ isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
if (sock->fd != (uv_os_sock_t)(-1)) {
|
||||
isc__nm_tcp_close(sock);
|
||||
}
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -286,7 +280,7 @@ error:
|
|||
isc__nm_failed_connect_cb(sock, req, result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize) {
|
||||
|
|
@ -295,7 +289,6 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
isc__netievent_tcpconnect_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
sa_family_t sa_family;
|
||||
uv_os_sock_t fd;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
REQUIRE(local != NULL);
|
||||
|
|
@ -303,22 +296,13 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sa_family = peer->addr.type.sa.sa_family;
|
||||
|
||||
/*
|
||||
* The socket() call can fail spuriously on FreeBSD 12, so we need to
|
||||
* handle the failure early and gracefully.
|
||||
*/
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_tcpsocket, local);
|
||||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->fd = fd;
|
||||
sock->fd = (uv_os_sock_t)-1;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
|
|
@ -328,6 +312,18 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
req->local = local->addr;
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface->addr);
|
||||
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
}
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, false);
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_detach(&sock);
|
||||
return;
|
||||
}
|
||||
|
||||
ievent = isc__nm_get_netievent_tcpconnect(mgr, sock, req);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
|
|
@ -343,17 +339,12 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
LOCK(&sock->lock);
|
||||
result = sock->result;
|
||||
while (result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
result = sock->result;
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static uv_os_sock_t
|
||||
|
|
|
|||
|
|
@ -180,9 +180,10 @@ isc__nm_async_tcpdnsconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
result = tcpdns_connect_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);
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -251,7 +252,7 @@ error:
|
|||
isc__nm_failed_connect_cb(sock, req, result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize) {
|
||||
|
|
@ -260,7 +261,6 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
isc__netievent_tcpdnsconnect_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
sa_family_t sa_family;
|
||||
uv_os_sock_t fd;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
REQUIRE(local != NULL);
|
||||
|
|
@ -268,27 +268,14 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sa_family = peer->addr.type.sa.sa_family;
|
||||
|
||||
/*
|
||||
* The socket() call can fail spuriously on FreeBSD 12, so we need to
|
||||
* handle the failure early and gracefully.
|
||||
*/
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_tcpdnssocket, local);
|
||||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->fd = fd;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
result = isc__nm_socket_connectiontimeout(fd, 120 * 1000); /* 2 mins */
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
|
|
@ -296,6 +283,22 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
req->local = local->addr;
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface->addr);
|
||||
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
}
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_detach(&sock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 2 minute timeout */
|
||||
result = isc__nm_socket_connectiontimeout(sock->fd, 120 * 1000);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
ievent = isc__nm_get_netievent_tcpdnsconnect(mgr, sock, req);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
|
|
@ -310,18 +313,14 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
LOCK(&sock->lock);
|
||||
result = sock->result;
|
||||
while (result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
result = sock->result;
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static uv_os_sock_t
|
||||
|
|
|
|||
|
|
@ -196,9 +196,10 @@ isc__nm_async_tlsdnsconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
result = tlsdns_connect_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_tlsdns_close(sock);
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -302,7 +303,7 @@ error:
|
|||
isc__nm_failed_connect_cb(sock, req, result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize, isc_tlsctx_t *sslctx) {
|
||||
|
|
@ -311,7 +312,6 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
isc__netievent_tlsdnsconnect_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
sa_family_t sa_family;
|
||||
uv_os_sock_t fd;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
REQUIRE(local != NULL);
|
||||
|
|
@ -320,29 +320,15 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sa_family = peer->addr.type.sa.sa_family;
|
||||
|
||||
/*
|
||||
* The socket() call can fail spuriously on FreeBSD 12, so we
|
||||
* need to handle the failure early and gracefully.
|
||||
*/
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_tlsdnssocket, local);
|
||||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->fd = fd;
|
||||
sock->tls.ctx = sslctx;
|
||||
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
result = isc__nm_socket_connectiontimeout(fd, 120 * 1000); /* 2 mins */
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
|
|
@ -350,6 +336,22 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
req->local = local->addr;
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface->addr);
|
||||
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
}
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_detach(&sock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 2 minute timeout */
|
||||
result = isc__nm_socket_connectiontimeout(sock->fd, 120 * 1000);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
ievent = isc__nm_get_netievent_tlsdnsconnect(mgr, sock, req);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
|
|
@ -365,17 +367,12 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
LOCK(&sock->lock);
|
||||
result = sock->result;
|
||||
while (result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
result = sock->result;
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static uv_os_sock_t
|
||||
|
|
|
|||
|
|
@ -835,13 +835,12 @@ isc__nm_tls_stoplistening(isc_nmsocket_t *sock) {
|
|||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_tlsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, SSL_CTX *ctx,
|
||||
unsigned int timeout, size_t extrahandlesize) {
|
||||
isc_nmsocket_t *nsock = NULL, *tsock = NULL;
|
||||
isc__netievent_tlsconnect_t *ievent = NULL;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
#if defined(NETMGR_TRACE) && defined(NETMGR_TRACE_VERBOSE)
|
||||
fprintf(stderr, "TLS: isc_nm_tlsconnect(): in net thread: %s\n",
|
||||
isc__nm_in_netthread() ? "yes" : "no");
|
||||
|
|
@ -880,20 +879,14 @@ isc_nm_tlsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
}
|
||||
|
||||
LOCK(&nsock->lock);
|
||||
result = nsock->result;
|
||||
while (result == ISC_R_DEFAULT) {
|
||||
while (nsock->result == ISC_R_DEFAULT) {
|
||||
WAIT(&nsock->cond, &nsock->lock);
|
||||
result = nsock->result;
|
||||
}
|
||||
atomic_store(&nsock->active, true);
|
||||
BROADCAST(&nsock->scond);
|
||||
UNLOCK(&nsock->lock);
|
||||
INSIST(VALID_NMSOCK(nsock));
|
||||
isc__nmsocket_detach(&tsock);
|
||||
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -936,6 +929,11 @@ isc__nm_async_tlsconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
UNUSED(worker);
|
||||
|
||||
if (isc__nm_closing(tlssock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to initialize SSL now to reference SSL_CTX properly.
|
||||
*/
|
||||
|
|
@ -948,20 +946,11 @@ isc__nm_async_tlsconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
tlssock->tid = isc_nm_tid();
|
||||
tlssock->tlsstream.state = TLS_INIT;
|
||||
|
||||
result = isc_nm_tcpconnect(worker->mgr, (isc_nmiface_t *)&ievent->local,
|
||||
(isc_nmiface_t *)&ievent->peer,
|
||||
tcp_connected, tlssock,
|
||||
tlssock->connect_timeout, 0);
|
||||
isc_nm_tcpconnect(worker->mgr, (isc_nmiface_t *)&ievent->local,
|
||||
(isc_nmiface_t *)&ievent->peer, tcp_connected,
|
||||
tlssock, tlssock->connect_timeout, 0);
|
||||
|
||||
/*
|
||||
* Sometimes on Linux, socket creation might fail if there are
|
||||
* already too many socket descriptors. In such a case the
|
||||
* connect callback is not going to be called.
|
||||
*/
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
update_result(tlssock, result);
|
||||
update_result(tlssock, ISC_R_SUCCESS);
|
||||
return;
|
||||
|
||||
error:
|
||||
|
|
|
|||
|
|
@ -617,7 +617,6 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
|
||||
r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
|
||||
if (r != 0) {
|
||||
isc__nm_closesocket(sock->fd);
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -702,7 +701,7 @@ isc__nm_async_udpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_udp_close(sock);
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
} else {
|
||||
/*
|
||||
* The callback has to be called after the socket has been
|
||||
|
|
@ -717,7 +716,7 @@ isc__nm_async_udpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize) {
|
||||
|
|
@ -726,7 +725,6 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
isc__netievent_udpconnect_t *event = NULL;
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
sa_family_t sa_family;
|
||||
uv_os_sock_t fd;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
REQUIRE(local != NULL);
|
||||
|
|
@ -734,15 +732,6 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sa_family = peer->addr.type.sa.sa_family;
|
||||
|
||||
/*
|
||||
* The socket() call can fail spuriously on FreeBSD 12, so we
|
||||
* need to handle the failure early and gracefully.
|
||||
*/
|
||||
result = isc__nm_socket(sa_family, SOCK_DGRAM, 0, &fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_udpsocket, local);
|
||||
|
||||
|
|
@ -751,10 +740,27 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
sock->read_timeout = timeout;
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->peer = peer->addr;
|
||||
sock->fd = fd;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
req->peer = peer->addr;
|
||||
req->local = local->addr;
|
||||
|
||||
result = isc__nm_socket(sa_family, SOCK_DGRAM, 0, &sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
}
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_detach(&sock);
|
||||
return;
|
||||
}
|
||||
|
||||
result = isc__nm_socket_reuse(sock->fd);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS ||
|
||||
result == ISC_R_NOTIMPLEMENTED);
|
||||
|
|
@ -767,12 +773,6 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
(void)isc__nm_socket_dontfrag(sock->fd, sa_family);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
req->peer = peer->addr;
|
||||
req->local = local->addr;
|
||||
|
||||
event = isc__nm_get_netievent_udpconnect(mgr, sock, req);
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
|
|
@ -788,17 +788,12 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
(isc__netievent_t *)event);
|
||||
}
|
||||
LOCK(&sock->lock);
|
||||
result = sock->result;
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
result = sock->result;
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
ENSURE(result != ISC_R_DEFAULT);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ static uint64_t stop_magic = 0;
|
|||
static uv_buf_t send_msg = { .base = (char *)&send_magic,
|
||||
.len = sizeof(send_magic) };
|
||||
|
||||
static atomic_uint_fast64_t nsends;
|
||||
static atomic_int_fast64_t nsends;
|
||||
|
||||
static atomic_uint_fast64_t ssends;
|
||||
static atomic_uint_fast64_t sreads;
|
||||
|
|
@ -71,6 +71,8 @@ static bool reuse_supported = true;
|
|||
|
||||
static atomic_bool POST = ATOMIC_VAR_INIT(true);
|
||||
|
||||
static atomic_bool slowdown = ATOMIC_VAR_INIT(false);
|
||||
|
||||
static atomic_bool use_TLS = ATOMIC_VAR_INIT(false);
|
||||
static isc_tlsctx_t *server_tlsctx = NULL;
|
||||
static isc_tlsctx_t *client_tlsctx = NULL;
|
||||
|
|
@ -117,6 +119,7 @@ connect_send_cb(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
memmove(&data, arg, sizeof(data));
|
||||
isc_mem_put(handle->sock->mgr->mctx, arg, sizeof(data));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&slowdown, true);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -135,11 +138,10 @@ error:
|
|||
data.region.length);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
connect_send_request(isc_nm_t *mgr, const char *uri, bool post,
|
||||
isc_region_t *region, isc_nm_recv_cb_t cb, void *cbarg,
|
||||
bool tls, unsigned int timeout) {
|
||||
isc_result_t result;
|
||||
isc_region_t copy;
|
||||
csdata_t *data = NULL;
|
||||
isc_tlsctx_t *ctx = NULL;
|
||||
|
|
@ -153,10 +155,8 @@ connect_send_request(isc_nm_t *mgr, const char *uri, bool post,
|
|||
ctx = client_tlsctx;
|
||||
}
|
||||
|
||||
result = isc_nm_httpconnect(
|
||||
mgr, NULL, (isc_nmiface_t *)&tcp_listen_addr, uri, post,
|
||||
connect_send_cb, data, ctx, timeout, 0);
|
||||
return (result);
|
||||
isc_nm_httpconnect(mgr, NULL, (isc_nmiface_t *)&tcp_listen_addr, uri,
|
||||
post, connect_send_cb, data, ctx, timeout, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -372,28 +372,18 @@ sockaddr_to_url(isc_sockaddr_t *sa, const bool https, char *outbuf,
|
|||
static void
|
||||
doh_receive_reply_cb(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *cbarg) {
|
||||
uint_fast64_t sends = atomic_load(&nsends);
|
||||
assert_non_null(handle);
|
||||
UNUSED(cbarg);
|
||||
UNUSED(region);
|
||||
|
||||
(void)atomic_fetch_sub(&nsends, 1);
|
||||
|
||||
if (eresult == ISC_R_SUCCESS) {
|
||||
atomic_fetch_add(&csends, 1);
|
||||
atomic_fetch_add(&creads, 1);
|
||||
if (sends > 0) {
|
||||
atomic_fetch_sub(&nsends, 1);
|
||||
}
|
||||
isc_nm_resumeread(handle);
|
||||
} else {
|
||||
/* We failed to connect; try again */
|
||||
while (sends > 0) {
|
||||
/* Continue until we subtract or we are done */
|
||||
if (atomic_compare_exchange_weak(&nsends, &sends,
|
||||
sends - 1)) {
|
||||
sends--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
atomic_store(&was_error, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -486,11 +476,10 @@ doh_noop(void **state) {
|
|||
|
||||
sockaddr_to_url(&tcp_listen_addr, false, req_url, sizeof(req_url),
|
||||
DOH_PATH);
|
||||
(void)connect_send_request(
|
||||
connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
noop_read_cb, NULL, atomic_load(&use_TLS), 30000);
|
||||
connect_send_request(connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
noop_read_cb, NULL, atomic_load(&use_TLS), 30000);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
|
|
@ -531,11 +520,10 @@ doh_noresponse(void **state) {
|
|||
|
||||
sockaddr_to_url(&tcp_listen_addr, false, req_url, sizeof(req_url),
|
||||
DOH_PATH);
|
||||
(void)connect_send_request(
|
||||
connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
noop_read_cb, NULL, atomic_load(&use_TLS), 30000);
|
||||
connect_send_request(connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
noop_read_cb, NULL, atomic_load(&use_TLS), 30000);
|
||||
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
|
|
@ -558,7 +546,7 @@ doh_noresponse_GET(void **state) {
|
|||
static void
|
||||
doh_receive_send_reply_cb(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *cbarg) {
|
||||
uint_fast64_t sends = atomic_load(&nsends);
|
||||
int_fast64_t sends = atomic_fetch_sub(&nsends, 1);
|
||||
assert_non_null(handle);
|
||||
UNUSED(region);
|
||||
|
||||
|
|
@ -567,7 +555,6 @@ doh_receive_send_reply_cb(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
atomic_fetch_add(&creads, 1);
|
||||
if (sends > 0) {
|
||||
size_t i;
|
||||
atomic_fetch_sub(&nsends, 1);
|
||||
for (i = 0; i < NWRITES / 2; i++) {
|
||||
eresult = isc__nm_http_request(
|
||||
handle,
|
||||
|
|
@ -579,15 +566,6 @@ doh_receive_send_reply_cb(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
/* We failed to connect; try again */
|
||||
while (sends > 0) {
|
||||
/* Continue until we subtract or we are done */
|
||||
if (atomic_compare_exchange_weak(&nsends, &sends,
|
||||
sends - 1)) {
|
||||
sends--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
atomic_store(&was_error, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -596,25 +574,27 @@ static isc_threadresult_t
|
|||
doh_connect_thread(isc_threadarg_t arg) {
|
||||
isc_nm_t *connect_nm = (isc_nm_t *)arg;
|
||||
char req_url[256];
|
||||
isc_result_t result;
|
||||
int64_t sends = atomic_load(&nsends);
|
||||
|
||||
sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url,
|
||||
sizeof(req_url), DOH_PATH);
|
||||
|
||||
while (atomic_load(&nsends) > 0) {
|
||||
result = connect_send_request(
|
||||
while (sends > 0) {
|
||||
/*
|
||||
* We need to back off and slow down if we start getting
|
||||
* errors, to prevent a thundering herd problem.
|
||||
*/
|
||||
if (atomic_load(&slowdown)) {
|
||||
usleep(1000 * workers);
|
||||
atomic_store(&slowdown, false);
|
||||
}
|
||||
connect_send_request(
|
||||
connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
doh_receive_send_reply_cb, NULL, atomic_load(&use_TLS),
|
||||
30000);
|
||||
/* protection against "too many open files" */
|
||||
#ifndef _WIN32
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(result == ISC_R_TOOMANYOPENFILES);
|
||||
usleep(1000 * workers);
|
||||
}
|
||||
#endif
|
||||
sends = atomic_load(&nsends);
|
||||
}
|
||||
|
||||
return ((isc_threadresult_t)0);
|
||||
|
|
@ -642,13 +622,11 @@ doh_recv_one(void **state) {
|
|||
|
||||
sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url,
|
||||
sizeof(req_url), DOH_PATH);
|
||||
result = connect_send_request(
|
||||
connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
doh_receive_reply_cb, NULL, atomic_load(&use_TLS), 30000);
|
||||
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
connect_send_request(connect_nm, req_url, atomic_load(&POST),
|
||||
&(isc_region_t){ .base = (uint8_t *)send_msg.base,
|
||||
.length = send_msg.len },
|
||||
doh_receive_reply_cb, NULL, atomic_load(&use_TLS),
|
||||
30000);
|
||||
|
||||
while (atomic_load(&nsends) > 0) {
|
||||
if (atomic_load(&was_error)) {
|
||||
|
|
@ -766,12 +744,10 @@ doh_recv_two(void **state) {
|
|||
ctx = client_tlsctx;
|
||||
}
|
||||
|
||||
result = isc_nm_httpconnect(
|
||||
connect_nm, NULL, (isc_nmiface_t *)&tcp_listen_addr, req_url,
|
||||
atomic_load(&POST), doh_connect_send_two_requests_cb, NULL, ctx,
|
||||
5000, 0);
|
||||
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_httpconnect(connect_nm, NULL, (isc_nmiface_t *)&tcp_listen_addr,
|
||||
req_url, atomic_load(&POST),
|
||||
doh_connect_send_two_requests_cb, NULL, ctx, 5000,
|
||||
0);
|
||||
|
||||
while (atomic_load(&nsends) > 0) {
|
||||
if (atomic_load(&was_error)) {
|
||||
|
|
|
|||
|
|
@ -456,12 +456,15 @@ unref:
|
|||
static void
|
||||
connect_connect_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
|
||||
isc_nmhandle_t *readhandle = NULL;
|
||||
|
||||
UNUSED(cbarg);
|
||||
|
||||
F();
|
||||
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
|
||||
if (eresult != ISC_R_SUCCESS) {
|
||||
goto unref;
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_fetch_add(&cconnects, 1);
|
||||
|
|
@ -471,9 +474,6 @@ connect_connect_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
|
|||
isc_nm_read(handle, connect_read_cb, NULL);
|
||||
|
||||
connect_send(handle);
|
||||
|
||||
unref:
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -564,40 +564,27 @@ stream_accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
typedef isc_result_t (*connect_func)(isc_nm_t *);
|
||||
typedef void (*connect_func)(isc_nm_t *);
|
||||
|
||||
static isc_threadresult_t
|
||||
connect_thread(isc_threadarg_t arg) {
|
||||
connect_func connect = (connect_func)arg;
|
||||
isc_result_t result;
|
||||
isc_sockaddr_t connect_addr;
|
||||
|
||||
connect_addr = (isc_sockaddr_t){ .length = 0 };
|
||||
isc_sockaddr_fromin6(&connect_addr, &in6addr_loopback, 0);
|
||||
|
||||
while (atomic_load(&do_send)) {
|
||||
uint_fast32_t active =
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
if (active >= workers) {
|
||||
uint_fast32_t active = isc_refcount_current(&active_cconnects);
|
||||
if (active > workers) {
|
||||
/*
|
||||
* If we have more active connections than workers start
|
||||
* slowing down the connections to prevent the
|
||||
* If we have more active connections than workers,
|
||||
* start slowing down the connections to prevent the
|
||||
* thundering herd problem.
|
||||
*/
|
||||
usleep((active - workers) * 1000);
|
||||
}
|
||||
result = connect(connect_nm);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/*
|
||||
* Also back-off and slow down if we start getting
|
||||
* errors to prevent the thundering herd problem. This
|
||||
* could especially happen on FreeBSD where socket()
|
||||
* call can fail because of system limits and in such
|
||||
* case it's not such good idea to try again quickly.
|
||||
*/
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
connect(connect_nm);
|
||||
}
|
||||
|
||||
return ((isc_threadresult_t)0);
|
||||
|
|
@ -605,11 +592,12 @@ connect_thread(isc_threadarg_t arg) {
|
|||
|
||||
/* UDP */
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
udp_connect(isc_nm_t *nm) {
|
||||
return (isc_nm_udpconnect(nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0));
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_udpconnect(nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -659,20 +647,12 @@ mock_listenudp_uv_udp_recv_start(void **state __attribute__((unused))) {
|
|||
|
||||
static void
|
||||
mock_udpconnect_uv_udp_open(void **state __attribute__((unused))) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
WILL_RETURN(uv_udp_open, UV_ENOMEM);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
assert_int_not_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
|
|
@ -680,20 +660,12 @@ mock_udpconnect_uv_udp_open(void **state __attribute__((unused))) {
|
|||
|
||||
static void
|
||||
mock_udpconnect_uv_udp_bind(void **state __attribute__((unused))) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
WILL_RETURN(uv_udp_bind, UV_ENOMEM);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
assert_int_not_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
|
|
@ -702,20 +674,12 @@ mock_udpconnect_uv_udp_bind(void **state __attribute__((unused))) {
|
|||
#if HAVE_UV_UDP_CONNECT
|
||||
static void
|
||||
mock_udpconnect_uv_udp_connect(void **state __attribute__((unused))) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
WILL_RETURN(uv_udp_connect, UV_ENOMEM);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
assert_int_not_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
|
|
@ -724,20 +688,12 @@ mock_udpconnect_uv_udp_connect(void **state __attribute__((unused))) {
|
|||
|
||||
static void
|
||||
mock_udpconnect_uv_recv_buffer_size(void **state __attribute__((unused))) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
WILL_RETURN(uv_recv_buffer_size, UV_ENOMEM);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS); /* FIXME: should fail */
|
||||
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
|
|
@ -745,20 +701,12 @@ mock_udpconnect_uv_recv_buffer_size(void **state __attribute__((unused))) {
|
|||
|
||||
static void
|
||||
mock_udpconnect_uv_send_buffer_size(void **state __attribute__((unused))) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
WILL_RETURN(uv_send_buffer_size, UV_ENOMEM);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS); /* FIXME: should fail */
|
||||
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
|
|
@ -777,17 +725,10 @@ udp_noop(void **state __attribute__((unused))) {
|
|||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
|
|
@ -806,16 +747,10 @@ udp_noresponse(void **state __attribute__((unused))) {
|
|||
noop_recv_cb, NULL, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_EQ(csends, 1);
|
||||
|
|
@ -849,16 +784,10 @@ udp_recv_one(void **state __attribute__((unused))) {
|
|||
listen_read_cb, NULL, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -896,29 +825,17 @@ udp_recv_two(void **state __attribute__((unused))) {
|
|||
listen_read_cb, NULL, 0, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_udpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 2);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -1135,11 +1052,12 @@ udp_half_recv_half_send(void **state __attribute__((unused))) {
|
|||
static isc_quota_t *
|
||||
tcp_listener_init_quota(size_t nthreads);
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
tcp_connect(isc_nm_t *nm) {
|
||||
return (isc_nm_tcpconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, 1, 0));
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, 1, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1156,17 +1074,10 @@ tcp_noop(void **state __attribute__((unused))) {
|
|||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
noop_connect_cb, NULL, 1, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, noop_connect_cb,
|
||||
NULL, 1, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
|
|
@ -1186,16 +1097,10 @@ tcp_noresponse(void **state __attribute__((unused))) {
|
|||
&listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpconnect(connect_nm,
|
||||
(isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, 1, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, 1, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_EQ(csends, 1);
|
||||
|
|
@ -1231,16 +1136,10 @@ tcp_recv_one(void **state __attribute__((unused))) {
|
|||
&listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -1280,29 +1179,17 @@ tcp_recv_two(void **state __attribute__((unused))) {
|
|||
&listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 2);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -1532,7 +1419,7 @@ tcp_listener_init_quota(size_t nthreads) {
|
|||
isc_quota_max(&listener_quota, max_quota);
|
||||
quotap = &listener_quota;
|
||||
}
|
||||
return quotap;
|
||||
return (quotap);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1577,11 +1464,12 @@ tcp_half_recv_half_send_quota(void **state) {
|
|||
|
||||
/* TCPDNS */
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
tcpdns_connect(isc_nm_t *nm) {
|
||||
return (isc_nm_tcpdnsconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0));
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpdnsconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1599,15 +1487,9 @@ tcpdns_noop(void **state __attribute__((unused))) {
|
|||
assert_null(listen_sock);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpdnsconnect(connect_nm,
|
||||
(isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
noop_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tcpdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
|
|
@ -1632,11 +1514,9 @@ tcpdns_noresponse(void **state __attribute__((unused))) {
|
|||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_tcpdnsconnect(connect_nm,
|
||||
(isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tcpdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_EQ(csends, 1);
|
||||
|
|
@ -1672,14 +1552,9 @@ tcpdns_recv_one(void **state __attribute__((unused))) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpdnsconnect(connect_nm,
|
||||
(isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tcpdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -1718,31 +1593,17 @@ tcpdns_recv_two(void **state __attribute__((unused))) {
|
|||
NULL, listen_accept_cb, NULL, 0, 0, NULL, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tcpdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tcpdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 2);
|
||||
|
||||
|
|
@ -1961,12 +1822,13 @@ tcpdns_half_recv_half_send(void **state __attribute__((unused))) {
|
|||
|
||||
/* TLSDNS */
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
tlsdns_connect(isc_nm_t *nm) {
|
||||
return (isc_nm_tlsdnsconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx));
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1984,17 +1846,10 @@ tlsdns_noop(void **state __attribute__((unused))) {
|
|||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0, tcp_connect_tlsctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, noop_connect_cb,
|
||||
NULL, T_CONNECT, 0, tcp_connect_tlsctx);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
|
|
@ -2020,17 +1875,11 @@ tlsdns_noresponse(void **state __attribute__((unused))) {
|
|||
&listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
do {
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0, tcp_connect_tlsctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
} while (result != ISC_R_SUCCESS);
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, (isc_nmiface_t *)&connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_EQ(csends, 1);
|
||||
|
|
@ -2067,15 +1916,10 @@ tlsdns_recv_one(void **state __attribute__((unused))) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb, NULL,
|
||||
T_CONNECT, 0, tcp_connect_tlsctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tlsdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -2116,28 +1960,18 @@ tlsdns_recv_two(void **state __attribute__((unused))) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb, NULL,
|
||||
T_CONNECT, 0, tcp_connect_tlsctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tlsdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb, NULL,
|
||||
T_CONNECT, 0, tcp_connect_tlsctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_refcount_decrement(&active_cconnects);
|
||||
usleep(1000);
|
||||
}
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tlsdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 2);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ static atomic_uint_fast64_t csends;
|
|||
static atomic_uint_fast64_t creads;
|
||||
static atomic_uint_fast64_t ctimeouts;
|
||||
|
||||
static atomic_bool slowdown = ATOMIC_VAR_INIT(false);
|
||||
|
||||
static unsigned int workers = 0;
|
||||
|
||||
static bool reuse_supported = true;
|
||||
|
|
@ -389,6 +391,7 @@ tls_connect_connect_cb(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
|
||||
if (eresult != ISC_R_SUCCESS) {
|
||||
uint_fast64_t sends = atomic_load(&nsends);
|
||||
atomic_store(&slowdown, true);
|
||||
|
||||
/* We failed to connect; try again */
|
||||
while (sends > 0) {
|
||||
|
|
@ -431,10 +434,9 @@ tls_noop(void **state) {
|
|||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
||||
(void)isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr,
|
||||
noop_connect_cb, NULL, client_tlsctx, 1, 0);
|
||||
|
||||
isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr, noop_connect_cb,
|
||||
NULL, client_tlsctx, 1, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
|
||||
assert_int_equal(0, atomic_load(&cconnects));
|
||||
|
|
@ -462,10 +464,9 @@ tls_noresponse(void **state) {
|
|||
server_tlsctx, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
(void)isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr,
|
||||
noop_connect_cb, NULL, client_tlsctx, 1, 0);
|
||||
|
||||
isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr, noop_connect_cb,
|
||||
NULL, client_tlsctx, 1, 0);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -479,21 +480,23 @@ static isc_threadresult_t
|
|||
tls_connect_thread(isc_threadarg_t arg) {
|
||||
isc_nm_t *connect_nm = (isc_nm_t *)arg;
|
||||
isc_sockaddr_t tls_connect_addr;
|
||||
isc_result_t result;
|
||||
|
||||
tls_connect_addr = (isc_sockaddr_t){ .length = 0 };
|
||||
isc_sockaddr_fromin6(&tls_connect_addr, &in6addr_loopback, 0);
|
||||
|
||||
while (atomic_load(&nsends) > 0) {
|
||||
result = isc_nm_tlsconnect(
|
||||
/*
|
||||
* We need to back off and slow down if we start getting
|
||||
* errors, to prevent a thundering herd problem.
|
||||
*/
|
||||
if (atomic_load(&slowdown)) {
|
||||
usleep(1000 * workers);
|
||||
atomic_store(&slowdown, false);
|
||||
}
|
||||
isc_nm_tlsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_connect_connect_cb, NULL, client_tlsctx, 1, 0);
|
||||
/* protection against "too many open files" */
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_fetch_sub(&nsends, 1);
|
||||
usleep(1000 * workers);
|
||||
}
|
||||
}
|
||||
|
||||
return ((isc_threadresult_t)0);
|
||||
|
|
@ -518,10 +521,9 @@ tls_recv_one(void **state) {
|
|||
server_tlsctx, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
(void)isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_connect_connect_cb, NULL, client_tlsctx,
|
||||
1000, 0);
|
||||
isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_connect_connect_cb, NULL, client_tlsctx, 1000, 0);
|
||||
|
||||
while (atomic_load(&nsends) > 0) {
|
||||
isc_thread_yield();
|
||||
|
|
@ -573,11 +575,10 @@ tls_recv_two(void **state) {
|
|||
server_tlsctx, &listen_sock);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_nm_tlsconnect(
|
||||
connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr, tls_connect_connect_cb, NULL,
|
||||
client_tlsctx, 100000, 0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_nm_tlsconnect(connect_nm, (isc_nmiface_t *)&tls_connect_addr,
|
||||
(isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_connect_connect_cb, NULL, client_tlsctx, 100000,
|
||||
0);
|
||||
|
||||
while (atomic_load(&nsends) > 0) {
|
||||
isc_thread_yield();
|
||||
|
|
|
|||
|
|
@ -111,7 +111,9 @@ __wrap_uv_udp_bind(uv_udp_t *handle, const struct sockaddr *addr,
|
|||
return (atomic_load(&__state_uv_udp_bind));
|
||||
}
|
||||
|
||||
static atomic_int __state_uv_udp_connect = ATOMIC_VAR_INIT(0);
|
||||
static atomic_int __state_uv_udp_connect
|
||||
__attribute__((unused)) = ATOMIC_VAR_INIT(0);
|
||||
|
||||
#if HAVE_UV_UDP_CONNECT
|
||||
int
|
||||
__wrap_uv_udp_connect(uv_udp_t *handle, const struct sockaddr *addr) {
|
||||
|
|
@ -122,7 +124,9 @@ __wrap_uv_udp_connect(uv_udp_t *handle, const struct sockaddr *addr) {
|
|||
}
|
||||
#endif /* HAVE_UV_UDP_CONNECT */
|
||||
|
||||
static atomic_int __state_uv_udp_getpeername = ATOMIC_VAR_INIT(0);
|
||||
static atomic_int __state_uv_udp_getpeername
|
||||
__attribute__((unused)) = ATOMIC_VAR_INIT(0);
|
||||
|
||||
#if HAVE_UV_UDP_CONNECT
|
||||
int
|
||||
__wrap_uv_udp_getpeername(const uv_udp_t *handle, struct sockaddr *name,
|
||||
|
|
|
|||
Loading…
Reference in a new issue