static void
rndc_startconnect(isc_sockaddr_t *addr) {
- isc_result_t result;
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_t *local = NULL;
}
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
}
}
- INSIST(optind < argc);
-
{
struct addrinfo hints = {
.ai_family = family,
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
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);
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:
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();
*/
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);
* 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);
*
*/
-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);
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);
* '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,
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;
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
}
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
}
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;
.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
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);
done:
result = isc__nm_uverr2result(r);
-error:
LOCK(&sock->lock);
sock->result = result;
SIGNAL(&sock->cond);
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);
}
/*
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) {
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);
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);
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()) {
(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
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);
}
/*
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) {
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);
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;
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()) {
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
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);
}
/*
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) {
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);
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;
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()) {
(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
}
}
-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");
}
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
UNUSED(worker);
+ if (isc__nm_closing(tlssock)) {
+ result = ISC_R_CANCELED;
+ goto error;
+ }
+
/*
* We need to initialize SSL now to reference SSL_CTX properly.
*/
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:
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;
}
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
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) {
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);
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);
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);
(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()) {
(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
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;
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;
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;
}
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;
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
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);
}
}
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);
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);
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);
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,
}
}
} 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);
}
}
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);
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)) {
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)) {
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);
isc_nm_read(handle, connect_read_cb, NULL);
connect_send(handle);
-
-unref:
- isc_refcount_decrement(&active_cconnects);
}
static void
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);
/* 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
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;
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;
#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;
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;
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;
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);
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);
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);
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);
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
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);
&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);
&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);
&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);
isc_quota_max(&listener_quota, max_quota);
quotap = &listener_quota;
}
- return quotap;
+ return (quotap);
}
static void
/* 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
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);
}
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);
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);
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);
/* 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
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);
&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);
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);
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);
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;
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) {
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));
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);
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);
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();
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();
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) {
}
#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,