mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-03 22:08:25 -04:00
Merge branch '2401-ISC_R_TIMEDOUT-is-recoverable' into 'main'
netmgr: Make it possible to recover from ISC_R_TIMEDOUT Closes #2401 See merge request isc-projects/bind9!4845
This commit is contained in:
commit
81c5f5e6a8
19 changed files with 969 additions and 969 deletions
7
CHANGES
7
CHANGES
|
|
@ -1,3 +1,10 @@
|
|||
5612. [bug] Continued refactoring of the network manager:
|
||||
- allow recovery from read and connect timeout events
|
||||
- ensure that calls to isc_nm_*connect() always
|
||||
return the connection status via a callback
|
||||
function.
|
||||
[GL #2401]
|
||||
|
||||
5611. [func] Set "stale-answer-client-timeout" to "off" by default.
|
||||
[GL #2608]
|
||||
|
||||
|
|
|
|||
|
|
@ -1541,12 +1541,13 @@ _destroy_lookup(dig_lookup_t *lookup) {
|
|||
dig_server_t *s;
|
||||
void *ptr;
|
||||
|
||||
REQUIRE(lookup != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(lookup->q));
|
||||
|
||||
debug("destroy_lookup");
|
||||
|
||||
isc_refcount_destroy(&lookup->references);
|
||||
|
||||
REQUIRE(ISC_LIST_EMPTY(lookup->q));
|
||||
|
||||
s = ISC_LIST_HEAD(lookup->my_server_list);
|
||||
while (s != NULL) {
|
||||
debug("freeing server %p belonging to %p", s, lookup);
|
||||
|
|
@ -2794,12 +2795,11 @@ start_tcp(dig_query_t *query) {
|
|||
if (query->lookup->tls_mode) {
|
||||
result = isc_tlsctx_createclient(&query->tlsctx);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
result = isc_nm_tlsdnsconnect(
|
||||
netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr,
|
||||
tcp_connected, query, local_timeout, 0,
|
||||
query->tlsctx);
|
||||
check_result(result, "isc_nm_tlsdnsconnect");
|
||||
isc_nm_tlsdnsconnect(netmgr,
|
||||
(isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr,
|
||||
tcp_connected, query,
|
||||
local_timeout, 0, query->tlsctx);
|
||||
} else if (query->lookup->https_mode) {
|
||||
char uri[4096] = { 0 };
|
||||
snprintf(uri, sizeof(uri), "https://%s:%u%s",
|
||||
|
|
@ -2814,18 +2814,16 @@ start_tcp(dig_query_t *query) {
|
|||
query->tlsctx);
|
||||
}
|
||||
|
||||
result = isc_nm_httpconnect(
|
||||
netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr, uri,
|
||||
!query->lookup->https_get, tcp_connected, query,
|
||||
query->tlsctx, local_timeout, 0);
|
||||
check_result(result, "isc_nm_httpconnect");
|
||||
isc_nm_httpconnect(netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr,
|
||||
uri, !query->lookup->https_get,
|
||||
tcp_connected, query, query->tlsctx,
|
||||
local_timeout, 0);
|
||||
} else {
|
||||
result = isc_nm_tcpdnsconnect(
|
||||
isc_nm_tcpdnsconnect(
|
||||
netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr,
|
||||
tcp_connected, query, local_timeout, 0);
|
||||
check_result(result, "isc_nm_tcpdnsconnect");
|
||||
}
|
||||
|
||||
/* XXX: set DSCP */
|
||||
|
|
@ -2900,13 +2898,15 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
query_detach(&query);
|
||||
return;
|
||||
} else if (eresult != ISC_R_SUCCESS) {
|
||||
dig_lookup_t *l = query->lookup;
|
||||
|
||||
if (eresult != ISC_R_CANCELED) {
|
||||
debug("udp setup failed: %s",
|
||||
isc_result_totext(eresult));
|
||||
}
|
||||
if (query->tries == 0) {
|
||||
query_detach(&query);
|
||||
}
|
||||
|
||||
lookup_detach(&l);
|
||||
query_detach(&query);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2993,24 +2993,9 @@ start_udp(dig_query_t *query) {
|
|||
}
|
||||
}
|
||||
|
||||
query->tries = 3;
|
||||
do {
|
||||
int local_timeout = timeout * 1000;
|
||||
if (local_timeout == 0) {
|
||||
local_timeout = UDP_TIMEOUT * 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* On FreeBSD the UDP connect() call sometimes results
|
||||
* in a spurious transient EADDRINUSE. Try a few more times
|
||||
* before giving up.
|
||||
*/
|
||||
debug("isc_nm_udpconnect(): %d tries left", --query->tries);
|
||||
result = isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr,
|
||||
udp_ready, query, local_timeout, 0);
|
||||
} while (result != ISC_R_SUCCESS && query->tries > 0);
|
||||
check_result(result, "isc_nm_udpconnect");
|
||||
isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr, udp_ready, query,
|
||||
(timeout ? timeout : UDP_TIMEOUT) * 1000, 0);
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
|
|||
|
|
@ -208,7 +208,6 @@ struct dig_query {
|
|||
isc_time_t time_recv;
|
||||
uint64_t byte_count;
|
||||
isc_timer_t *timer;
|
||||
uint8_t tries;
|
||||
isc_tlsctx_t *tlsctx;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1058,7 +1058,7 @@ http_call_connect_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
req->handle = isc__nmhandle_get(sock, &sock->peer, &sock->iface->addr);
|
||||
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb_force_async(sock, req, result);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -854,8 +854,6 @@ struct isc_nmsocket {
|
|||
* TCP read/connect timeout timers.
|
||||
*/
|
||||
uv_timer_t timer;
|
||||
bool timer_initialized;
|
||||
bool timer_running;
|
||||
uint64_t read_timeout;
|
||||
uint64_t connect_timeout;
|
||||
|
||||
|
|
@ -1136,6 +1134,13 @@ isc___nmsocket_prep_destroy(isc_nmsocket_t *sock FLARG);
|
|||
* if there are no remaining references or active handles.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nmsocket_shutdown(isc_nmsocket_t *sock);
|
||||
/*%<
|
||||
* Initiate the socket shutdown which actively calls the active
|
||||
* callbacks.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc__nmsocket_active(isc_nmsocket_t *sock);
|
||||
/*%<
|
||||
|
|
@ -1167,17 +1172,15 @@ void
|
|||
isc__nmsocket_timer_start(isc_nmsocket_t *sock);
|
||||
void
|
||||
isc__nmsocket_timer_restart(isc_nmsocket_t *sock);
|
||||
bool
|
||||
isc__nmsocket_timer_running(isc_nmsocket_t *sock);
|
||||
/*%<
|
||||
* Start/stop/restart the read timeout on the socket
|
||||
* Start/stop/restart/check the timeout on the socket
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult);
|
||||
|
||||
void
|
||||
isc__nm_connectcb_force_async(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult);
|
||||
isc_result_t eresult, bool async);
|
||||
|
||||
void
|
||||
isc__nm_async_connectcb(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
|
|
@ -1850,7 +1853,8 @@ isc__nm_tcp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
|
|||
void
|
||||
isc__nm_tcpdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
|
||||
void
|
||||
isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
|
||||
isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
||||
bool async);
|
||||
|
||||
isc_result_t
|
||||
isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock);
|
||||
|
|
@ -1867,6 +1871,8 @@ void
|
|||
isc__nm_udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
const struct sockaddr *addr, unsigned flags);
|
||||
void
|
||||
isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
void
|
||||
isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
void
|
||||
isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
|
|
@ -1880,7 +1886,9 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock);
|
|||
void
|
||||
isc__nm_resume_processing(void *arg);
|
||||
bool
|
||||
isc__nm_inactive(isc_nmsocket_t *sock);
|
||||
isc__nmsocket_closing(isc_nmsocket_t *sock);
|
||||
bool
|
||||
isc__nm_closing(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_alloc_dnsbuf(isc_nmsocket_t *sock, size_t len);
|
||||
|
|
@ -1892,8 +1900,11 @@ void
|
|||
isc__nm_failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult);
|
||||
void
|
||||
isc__nm_failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
isc_result_t eresult);
|
||||
isc_result_t eresult, bool async);
|
||||
void
|
||||
isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
|
||||
isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result, bool async);
|
||||
|
||||
void
|
||||
isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
|
||||
|
||||
#define STREAM_CLIENTS_PER_CONN 23
|
||||
|
|
|
|||
|
|
@ -827,7 +827,6 @@ NETIEVENT_SOCKET_REQ_DEF(tcpconnect);
|
|||
NETIEVENT_SOCKET_REQ_DEF(tcpsend);
|
||||
NETIEVENT_SOCKET_REQ_DEF(tlssend);
|
||||
NETIEVENT_SOCKET_REQ_DEF(udpconnect);
|
||||
|
||||
NETIEVENT_SOCKET_REQ_RESULT_DEF(connectcb);
|
||||
NETIEVENT_SOCKET_REQ_RESULT_DEF(readcb);
|
||||
NETIEVENT_SOCKET_REQ_RESULT_DEF(sendcb);
|
||||
|
|
@ -987,15 +986,6 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
|
|||
|
||||
sock->pquota = NULL;
|
||||
|
||||
if (sock->timer_initialized) {
|
||||
sock->timer_initialized = false;
|
||||
/* We might be in timer callback */
|
||||
if (!uv_is_closing((uv_handle_t *)&sock->timer)) {
|
||||
uv_timer_stop(&sock->timer);
|
||||
uv_close((uv_handle_t *)&sock->timer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
isc_astack_destroy(sock->inactivehandles);
|
||||
|
||||
while ((uvreq = isc_astack_pop(sock->inactivereqs)) != NULL) {
|
||||
|
|
@ -1031,6 +1021,9 @@ nmsocket_maybe_destroy(isc_nmsocket_t *sock FLARG) {
|
|||
int active_handles;
|
||||
bool destroy = false;
|
||||
|
||||
NETMGR_TRACE_LOG("%s():%p->references = %" PRIuFAST32 "\n", __func__,
|
||||
sock, isc_refcount_current(&sock->references));
|
||||
|
||||
if (sock->parent != NULL) {
|
||||
/*
|
||||
* This is a child socket and cannot be destroyed except
|
||||
|
|
@ -1397,11 +1390,16 @@ isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
|
|||
#endif
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
if (sock->type == isc_nm_tcpsocket || sock->type == isc_nm_tlssocket ||
|
||||
(sock->type == isc_nm_udpsocket && atomic_load(&sock->client)) ||
|
||||
(sock->type == isc_nm_tcpdnssocket && atomic_load(&sock->client)) ||
|
||||
(sock->type == isc_nm_tlsdnssocket && atomic_load(&sock->client)))
|
||||
{
|
||||
switch (sock->type) {
|
||||
case isc_nm_udpsocket:
|
||||
case isc_nm_tcpdnssocket:
|
||||
case isc_nm_tlsdnssocket:
|
||||
if (!atomic_load(&sock->client)) {
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case isc_nm_tcpsocket:
|
||||
case isc_nm_tlssocket:
|
||||
INSIST(sock->statichandle == NULL);
|
||||
|
||||
/*
|
||||
|
|
@ -1411,6 +1409,9 @@ isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
|
|||
* handle and socket would never be freed.
|
||||
*/
|
||||
sock->statichandle = handle;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (sock->type == isc_nm_httpsocket && sock->h2.session) {
|
||||
|
|
@ -1520,6 +1521,9 @@ isc__nmhandle_detach(isc_nmhandle_t **handlep FLARG) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nmsocket_shutdown(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
nmhandle_detach_cb(isc_nmhandle_t **handlep FLARG) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
|
|
@ -1658,24 +1662,26 @@ isc__nm_failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
|||
|
||||
void
|
||||
isc__nm_failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
isc_result_t eresult) {
|
||||
isc_result_t eresult, bool async) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->connecting));
|
||||
REQUIRE(req->cb.connect != NULL);
|
||||
|
||||
atomic_store(&sock->connecting, false);
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
INSIST(atomic_compare_exchange_strong(&sock->connecting,
|
||||
&(bool){ true }, false));
|
||||
|
||||
isc__nmsocket_clearcb(sock);
|
||||
|
||||
isc__nm_connectcb(sock, req, eresult);
|
||||
isc__nm_connectcb(sock, req, eresult, async);
|
||||
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
||||
isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result, bool async) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
switch (sock->type) {
|
||||
case isc_nm_udpsocket:
|
||||
|
|
@ -1688,7 +1694,7 @@ isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
isc__nm_tcpdns_failed_read_cb(sock, result);
|
||||
return;
|
||||
case isc_nm_tlsdnssocket:
|
||||
isc__nm_tlsdns_failed_read_cb(sock, result);
|
||||
isc__nm_tlsdns_failed_read_cb(sock, result, async);
|
||||
return;
|
||||
default:
|
||||
INSIST(0);
|
||||
|
|
@ -1696,6 +1702,39 @@ isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nmsocket_connecttimeout_cb(uv_timer_t *timer) {
|
||||
uv_connect_t *uvreq = uv_handle_get_data((uv_handle_t *)timer);
|
||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)uvreq->handle);
|
||||
isc__nm_uvreq_t *req = uv_handle_get_data((uv_handle_t *)uvreq);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->connecting));
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
REQUIRE(VALID_NMHANDLE(req->handle));
|
||||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
|
||||
if (sock->tls.pending_req != NULL) {
|
||||
REQUIRE(req == sock->tls.pending_req);
|
||||
sock->tls.pending_req = NULL;
|
||||
}
|
||||
|
||||
/* Call the connect callback directly */
|
||||
|
||||
req->cb.connect(req->handle, ISC_R_TIMEDOUT, req->cbarg);
|
||||
|
||||
/* Timer is not running, cleanup and shutdown everything */
|
||||
if (!isc__nmsocket_timer_running(sock)) {
|
||||
INSIST(atomic_compare_exchange_strong(&sock->connecting,
|
||||
&(bool){ true }, false));
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nmsocket_shutdown(sock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
isc__nmsocket_readtimeout_cb(uv_timer_t *timer) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)timer);
|
||||
|
|
@ -1704,27 +1743,62 @@ isc__nmsocket_readtimeout_cb(uv_timer_t *timer) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->reading);
|
||||
|
||||
isc__nm_failed_read_cb(sock, ISC_R_TIMEDOUT);
|
||||
if (atomic_load(&sock->client)) {
|
||||
uv_timer_stop(timer);
|
||||
|
||||
if (sock->recv_cb != NULL) {
|
||||
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
||||
isc__nm_readcb(sock, req, ISC_R_TIMEDOUT);
|
||||
}
|
||||
|
||||
if (!isc__nmsocket_timer_running(sock)) {
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
}
|
||||
} else {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_TIMEDOUT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nmsocket_timer_restart(isc_nmsocket_t *sock) {
|
||||
int r = 0;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
if (sock->read_timeout == 0) {
|
||||
return;
|
||||
if (atomic_load(&sock->connecting)) {
|
||||
if (sock->connect_timeout == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
r = uv_timer_start(&sock->timer,
|
||||
isc__nmsocket_connecttimeout_cb,
|
||||
sock->connect_timeout + 10, 0);
|
||||
|
||||
} else {
|
||||
if (sock->read_timeout == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
r = uv_timer_start(&sock->timer, isc__nmsocket_readtimeout_cb,
|
||||
sock->read_timeout, 0);
|
||||
}
|
||||
|
||||
int r = uv_timer_start(&sock->timer, isc__nmsocket_readtimeout_cb,
|
||||
sock->read_timeout, 0);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
}
|
||||
|
||||
bool
|
||||
isc__nmsocket_timer_running(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
return (uv_is_active((uv_handle_t *)&sock->timer));
|
||||
}
|
||||
|
||||
void
|
||||
isc__nmsocket_timer_start(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
if (uv_is_active((uv_handle_t *)&sock->timer)) {
|
||||
if (isc__nmsocket_timer_running(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1735,9 +1809,7 @@ void
|
|||
isc__nmsocket_timer_stop(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
if (!uv_is_active((uv_handle_t *)&sock->timer)) {
|
||||
return;
|
||||
}
|
||||
/* uv_timer_stop() is idempotent, no need to check if running */
|
||||
|
||||
int r = uv_timer_stop(&sock->timer);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
|
|
@ -1751,13 +1823,21 @@ isc__nm_get_read_req(isc_nmsocket_t *sock, isc_sockaddr_t *sockaddr) {
|
|||
req->cb.recv = sock->recv_cb;
|
||||
req->cbarg = sock->recv_cbarg;
|
||||
|
||||
if (atomic_load(&sock->client)) {
|
||||
switch (sock->type) {
|
||||
case isc_nm_tcpsocket:
|
||||
case isc_nm_tlssocket:
|
||||
isc_nmhandle_attach(sock->statichandle, &req->handle);
|
||||
} else {
|
||||
req->handle = isc__nmhandle_get(sock, sockaddr, NULL);
|
||||
break;
|
||||
default:
|
||||
if (atomic_load(&sock->client)) {
|
||||
isc_nmhandle_attach(sock->statichandle, &req->handle);
|
||||
} else {
|
||||
req->handle = isc__nmhandle_get(sock, sockaddr, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return req;
|
||||
return (req);
|
||||
}
|
||||
|
||||
/*%<
|
||||
|
|
@ -1779,6 +1859,7 @@ isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
|
|||
REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE);
|
||||
size = ISC_NETMGR_RECVBUF_SIZE;
|
||||
break;
|
||||
case isc_nm_tcpsocket:
|
||||
case isc_nm_tcpdnssocket:
|
||||
break;
|
||||
case isc_nm_tlsdnssocket:
|
||||
|
|
@ -1797,7 +1878,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;
|
||||
|
|
@ -1817,6 +1898,10 @@ isc__nm_start_reading(isc_nmsocket_t *sock) {
|
|||
r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
|
||||
isc__nm_udp_read_cb);
|
||||
break;
|
||||
case isc_nm_tcpsocket:
|
||||
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
||||
isc__nm_tcp_read_cb);
|
||||
break;
|
||||
case isc_nm_tcpdnssocket:
|
||||
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
|
||||
isc__nm_tcpdns_read_cb);
|
||||
|
|
@ -1845,6 +1930,7 @@ isc__nm_stop_reading(isc_nmsocket_t *sock) {
|
|||
case isc_nm_udpsocket:
|
||||
r = uv_udp_recv_stop(&sock->uv_handle.udp);
|
||||
break;
|
||||
case isc_nm_tcpsocket:
|
||||
case isc_nm_tcpdnssocket:
|
||||
case isc_nm_tlsdnssocket:
|
||||
r = uv_read_stop(&sock->uv_handle.stream);
|
||||
|
|
@ -1858,7 +1944,12 @@ isc__nm_stop_reading(isc_nmsocket_t *sock) {
|
|||
}
|
||||
|
||||
bool
|
||||
isc__nm_inactive(isc_nmsocket_t *sock) {
|
||||
isc__nm_closing(isc_nmsocket_t *sock) {
|
||||
return (atomic_load(&sock->mgr->closing));
|
||||
}
|
||||
|
||||
bool
|
||||
isc__nmsocket_closing(isc_nmsocket_t *sock) {
|
||||
return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
|
||||
atomic_load(&sock->mgr->closing) ||
|
||||
(sock->server != NULL && !isc__nmsocket_active(sock->server)));
|
||||
|
|
@ -1945,7 +2036,7 @@ isc__nm_resume_processing(void *arg) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(!atomic_load(&sock->client));
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1987,9 +2078,7 @@ isc_nmhandle_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
|
|||
return;
|
||||
default:
|
||||
handle->sock->read_timeout = timeout;
|
||||
if (uv_is_active((uv_handle_t *)&handle->sock->timer)) {
|
||||
isc__nmsocket_timer_restart(handle->sock);
|
||||
}
|
||||
isc__nmsocket_timer_restart(handle->sock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2241,38 +2330,27 @@ isc_nm_stoplistening(isc_nmsocket_t *sock) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq, isc_result_t eresult,
|
||||
bool force_async) {
|
||||
isc__netievent_connectcb_t *ievent = NULL;
|
||||
|
||||
void
|
||||
isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult, bool async) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(VALID_UVREQ(uvreq));
|
||||
REQUIRE(VALID_NMHANDLE(uvreq->handle));
|
||||
|
||||
ievent = isc__nm_get_netievent_connectcb(sock->mgr, sock, uvreq,
|
||||
eresult);
|
||||
if (force_async) {
|
||||
if (!async) {
|
||||
isc__netievent_connectcb_t ievent = { .sock = sock,
|
||||
.req = uvreq,
|
||||
.result = eresult };
|
||||
isc__nm_async_connectcb(NULL, (isc__netievent_t *)&ievent);
|
||||
} 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);
|
||||
} else {
|
||||
isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult) {
|
||||
nm_connectcb(sock, uvreq, eresult, false);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_connectcb_force_async(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult) {
|
||||
nm_connectcb(sock, uvreq, eresult, true);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_connectcb(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_connectcb_t *ievent = (isc__netievent_connectcb_t *)ev0;
|
||||
|
|
@ -2403,23 +2481,8 @@ isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
nmhandle_detach_cb(&ievent->handle FLARG_PASS);
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown_walk_cb(uv_handle_t *handle, void *arg) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
UNUSED(arg);
|
||||
|
||||
if (uv_is_closing(handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_UDP:
|
||||
case UV_TCP:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
isc__nmsocket_shutdown(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
switch (sock->type) {
|
||||
case isc_nm_udpsocket:
|
||||
|
|
@ -2445,6 +2508,26 @@ shutdown_walk_cb(uv_handle_t *handle, void *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown_walk_cb(uv_handle_t *handle, void *arg) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
UNUSED(arg);
|
||||
|
||||
if (uv_is_closing(handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_UDP:
|
||||
case UV_TCP:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
isc__nmsocket_shutdown(sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
UNUSED(ev0);
|
||||
|
|
|
|||
|
|
@ -63,9 +63,6 @@ tcp_connect_cb(uv_connect_t *uvreq, int status);
|
|||
static void
|
||||
tcp_connection_cb(uv_stream_t *server, int status);
|
||||
|
||||
static void
|
||||
read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
|
||||
static void
|
||||
tcp_close_cb(uv_handle_t *uvhandle);
|
||||
|
||||
|
|
@ -86,25 +83,6 @@ stop_tcp_parent(isc_nmsocket_t *sock);
|
|||
static void
|
||||
stop_tcp_child(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
start_reading(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
stop_reading(isc_nmsocket_t *sock);
|
||||
|
||||
static isc__nm_uvreq_t *
|
||||
get_read_req(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
tcp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf);
|
||||
|
||||
static bool
|
||||
inactive(isc_nmsocket_t *sock) {
|
||||
return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
|
||||
atomic_load(&sock->mgr->closing) ||
|
||||
(sock->server != NULL && !isc__nmsocket_active(sock->server)));
|
||||
}
|
||||
|
||||
static void
|
||||
failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
||||
REQUIRE(sock->accepting);
|
||||
|
|
@ -135,23 +113,6 @@ failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
isc_result_t eresult) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->connecting));
|
||||
REQUIRE(req->cb.connect != NULL);
|
||||
|
||||
atomic_store(&sock->connecting, false);
|
||||
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, eresult);
|
||||
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc__networker_t *worker = NULL;
|
||||
|
|
@ -164,21 +125,20 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
result = isc__nm_socket_connectiontimeout(sock->fd,
|
||||
sock->connect_timeout);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
worker = &sock->mgr->workers[sock->tid];
|
||||
|
||||
atomic_store(&sock->connecting, true);
|
||||
|
||||
/* 2 minute timeout */
|
||||
result = isc__nm_socket_connectiontimeout(sock->fd, 120 * 1000);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
r = uv_tcp_init(&worker->loop, &sock->uv_handle.tcp);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
uv_handle_set_data(&sock->uv_handle.handle, sock);
|
||||
|
||||
r = uv_timer_init(&worker->loop, &sock->timer);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
|
||||
if (r != 0) {
|
||||
|
|
@ -207,11 +167,13 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
}
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]);
|
||||
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, &req->uv_req.connect);
|
||||
isc__nmsocket_timer_start(sock);
|
||||
|
||||
atomic_store(&sock->connected, true);
|
||||
|
||||
done:
|
||||
result = isc__nm_uverr2result(r);
|
||||
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
SIGNAL(&sock->cond);
|
||||
|
|
@ -246,7 +208,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -265,20 +227,35 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->connecting));
|
||||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
if (!atomic_load(&sock->connecting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
req = uv_handle_get_data((uv_handle_t *)uvreq);
|
||||
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
REQUIRE(VALID_NMHANDLE(req->handle));
|
||||
|
||||
/* Socket was closed midflight by isc__nm_tcp_shutdown() */
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
if (!atomic_load(&sock->connecting)) {
|
||||
/*
|
||||
* The connect was cancelled from timeout; just clean up
|
||||
* the req.
|
||||
*/
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
return;
|
||||
} else if (isc__nmsocket_closing(sock)) {
|
||||
/* Socket was closed midflight by isc__nm_tcp_shutdown() */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
} else if (status == UV_ETIMEDOUT) {
|
||||
/* Timeout status code here indicates hard error */
|
||||
result = ISC_R_TIMEDOUT;
|
||||
goto error;
|
||||
} else if (status != 0) {
|
||||
result = isc__nm_uverr2result(status);
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -296,15 +273,15 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS);
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS, false);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
failed_connect_cb(sock, req, result);
|
||||
isc__nm_failed_connect_cb(sock, req, result, false);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -313,7 +290,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);
|
||||
|
|
@ -321,22 +297,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);
|
||||
|
|
@ -346,6 +313,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()) {
|
||||
|
|
@ -361,17 +340,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
|
||||
|
|
@ -613,7 +587,7 @@ tcp_connection_cb(uv_stream_t *server, int status) {
|
|||
REQUIRE(VALID_NMSOCK(ssock));
|
||||
REQUIRE(ssock->tid == isc_nm_tid());
|
||||
|
||||
if (inactive(ssock)) {
|
||||
if (isc__nmsocket_closing(ssock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -693,7 +667,8 @@ failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->statichandle != NULL);
|
||||
|
||||
stop_reading(sock);
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
if (!sock->recv_read) {
|
||||
goto destroy;
|
||||
|
|
@ -701,7 +676,7 @@ failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
sock->recv_read = false;
|
||||
|
||||
if (sock->recv_cb != NULL) {
|
||||
isc__nm_uvreq_t *req = get_read_req(sock);
|
||||
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_readcb(sock, req, result);
|
||||
}
|
||||
|
|
@ -734,42 +709,6 @@ failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
|||
}
|
||||
}
|
||||
|
||||
static isc__nm_uvreq_t *
|
||||
get_read_req(isc_nmsocket_t *sock) {
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
|
||||
req = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
req->cb.recv = sock->recv_cb;
|
||||
req->cbarg = sock->recv_cbarg;
|
||||
isc_nmhandle_attach(sock->statichandle, &req->handle);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void
|
||||
start_reading(isc_nmsocket_t *sock) {
|
||||
if (sock->reading) {
|
||||
return;
|
||||
}
|
||||
|
||||
int r = uv_read_start(&sock->uv_handle.stream, tcp_alloc_cb, read_cb);
|
||||
REQUIRE(r == 0);
|
||||
sock->reading = true;
|
||||
}
|
||||
|
||||
static void
|
||||
stop_reading(isc_nmsocket_t *sock) {
|
||||
if (!sock->reading) {
|
||||
return;
|
||||
}
|
||||
|
||||
int r = uv_read_stop(&sock->uv_handle.stream);
|
||||
REQUIRE(r == 0);
|
||||
sock->reading = false;
|
||||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
|
@ -807,32 +746,6 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
|||
return;
|
||||
}
|
||||
|
||||
/*%<
|
||||
* Allocator for TCP read operations. Limited to size 2^16.
|
||||
*
|
||||
* Note this doesn't actually allocate anything, it just assigns the
|
||||
* worker's receive buffer to a socket, and marks it as "in use".
|
||||
*/
|
||||
static void
|
||||
tcp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
isc__networker_t *worker = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tcpsocket);
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
if (size > 65536) {
|
||||
size = 65536;
|
||||
}
|
||||
|
||||
worker = &sock->mgr->workers[sock->tid];
|
||||
INSIST(!worker->recvbuf_inuse);
|
||||
|
||||
buf->base = worker->recvbuf;
|
||||
buf->len = size;
|
||||
worker->recvbuf_inuse = true;
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_tcpstartread_t *ievent =
|
||||
|
|
@ -843,13 +756,13 @@ isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
UNUSED(worker);
|
||||
|
||||
if (inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
failed_read_cb(sock, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
start_reading(sock);
|
||||
isc__nm_start_reading(sock);
|
||||
isc__nmsocket_timer_start(sock);
|
||||
}
|
||||
|
||||
|
|
@ -886,7 +799,8 @@ isc__nm_async_tcppauseread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
UNUSED(worker);
|
||||
|
||||
stop_reading(sock);
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -921,8 +835,8 @@ isc__nm_tcp_resumeread(isc_nmhandle_t *handle) {
|
|||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
static void
|
||||
read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
||||
void
|
||||
isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream);
|
||||
isc__nm_uvreq_t *req = NULL;
|
||||
|
||||
|
|
@ -931,7 +845,7 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
|||
REQUIRE(sock->reading);
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
if (inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
failed_read_cb(sock, ISC_R_CANCELED);
|
||||
goto free;
|
||||
}
|
||||
|
|
@ -947,7 +861,7 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
|||
goto free;
|
||||
}
|
||||
|
||||
req = get_read_req(sock);
|
||||
req = isc__nm_get_read_req(sock, NULL);
|
||||
|
||||
/*
|
||||
* The callback will be called synchronously because the
|
||||
|
|
@ -1030,7 +944,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||
REQUIRE(VALID_NMSOCK(ssock));
|
||||
REQUIRE(ssock->tid == isc_nm_tid());
|
||||
|
||||
if (inactive(ssock)) {
|
||||
if (isc__nmsocket_closing(ssock)) {
|
||||
if (quota != NULL) {
|
||||
isc_quota_detach("a);
|
||||
}
|
||||
|
|
@ -1160,11 +1074,11 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
|||
static void
|
||||
tcp_send_cb(uv_write_t *req, int status) {
|
||||
isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data;
|
||||
isc_nmsocket_t *sock = uvreq->sock;
|
||||
|
||||
REQUIRE(VALID_UVREQ(uvreq));
|
||||
REQUIRE(VALID_NMHANDLE(uvreq->handle));
|
||||
|
||||
isc_nmsocket_t *sock = uvreq->sock;
|
||||
|
||||
if (status < 0) {
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_SENDFAIL]);
|
||||
failed_send_cb(sock, uvreq, isc__nm_uverr2result(status));
|
||||
|
|
@ -1204,7 +1118,7 @@ tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
|
||||
int r;
|
||||
|
||||
if (inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
|
|
@ -1240,10 +1154,7 @@ tcp_stop_cb(uv_handle_t *handle) {
|
|||
}
|
||||
|
||||
static void
|
||||
tcp_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
tcp_close_sock(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->closing));
|
||||
|
|
@ -1265,6 +1176,14 @@ tcp_close_cb(uv_handle_t *handle) {
|
|||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
tcp_close_sock(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
timer_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
|
@ -1272,6 +1191,8 @@ timer_close_cb(uv_handle_t *handle) {
|
|||
|
||||
if (sock->parent) {
|
||||
uv_close(&sock->uv_handle.handle, tcp_stop_cb);
|
||||
} else if (uv_is_closing(&sock->uv_handle.handle)) {
|
||||
tcp_close_sock(sock);
|
||||
} else {
|
||||
uv_close(&sock->uv_handle.handle, tcp_close_cb);
|
||||
}
|
||||
|
|
@ -1347,7 +1268,10 @@ tcp_close_direct(isc_nmsocket_t *sock) {
|
|||
isc_quota_detach(&sock->quota);
|
||||
}
|
||||
|
||||
stop_reading(sock);
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
uv_close((uv_handle_t *)&sock->timer, timer_close_cb);
|
||||
}
|
||||
|
||||
|
|
@ -1389,6 +1313,19 @@ isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
tcp_close_direct(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_close_connect_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -1403,11 +1340,18 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (atomic_load(&sock->connecting) || sock->accepting) {
|
||||
if (sock->accepting) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle) {
|
||||
if (atomic_load(&sock->connecting)) {
|
||||
isc_nmsocket_t *tsock = NULL;
|
||||
isc__nmsocket_attach(sock, &tsock);
|
||||
uv_close(&sock->uv_handle.handle, tcp_close_connect_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle != NULL) {
|
||||
failed_read_cb(sock, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1459,5 +1403,5 @@ isc__nm_tcp_listener_nactive(isc_nmsocket_t *listener) {
|
|||
|
||||
nactive = atomic_load(&listener->active_child_connections);
|
||||
INSIST(nactive >= 0);
|
||||
return nactive;
|
||||
return (nactive);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,11 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
|
||||
r = uv_timer_init(&worker->loop, &sock->timer);
|
||||
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) {
|
||||
|
|
@ -137,11 +141,14 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
}
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]);
|
||||
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, &req->uv_req.connect);
|
||||
isc__nmsocket_timer_start(sock);
|
||||
|
||||
atomic_store(&sock->connected, true);
|
||||
|
||||
done:
|
||||
result = isc__nm_uverr2result(r);
|
||||
|
||||
error:
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
SIGNAL(&sock->cond);
|
||||
|
|
@ -172,9 +179,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -193,20 +201,28 @@ tcpdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->connecting));
|
||||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
if (!atomic_load(&sock->connecting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
req = uv_handle_get_data((uv_handle_t *)uvreq);
|
||||
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
REQUIRE(VALID_NMHANDLE(req->handle));
|
||||
|
||||
/* Socket was closed midflight by isc__nm_tcpdns_shutdown() */
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
/* Socket was closed midflight by isc__nm_tcpdns_shutdown() */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
} else if (status == UV_ETIMEDOUT) {
|
||||
/* Timeout status code here indicates hard error */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
} else if (status != 0) {
|
||||
result = isc__nm_uverr2result(status);
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -224,15 +240,15 @@ tcpdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS);
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS, false);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
isc__nm_failed_connect_cb(sock, req, result);
|
||||
isc__nm_failed_connect_cb(sock, req, result, false);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -241,7 +257,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);
|
||||
|
|
@ -249,27 +264,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, timeout);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
|
|
@ -277,6 +279,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()) {
|
||||
|
|
@ -291,18 +309,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
|
||||
|
|
@ -546,7 +560,7 @@ tcpdns_connection_cb(uv_stream_t *server, int status) {
|
|||
REQUIRE(VALID_NMSOCK(ssock));
|
||||
REQUIRE(ssock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(ssock)) {
|
||||
if (isc__nmsocket_closing(ssock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -700,9 +714,9 @@ isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +741,7 @@ isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
|
|
@ -804,8 +818,8 @@ isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||
REQUIRE(sock->reading);
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, true);
|
||||
goto free;
|
||||
}
|
||||
|
||||
|
|
@ -815,7 +829,7 @@ isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||
sock->statsindex[STATID_RECVFAIL]);
|
||||
}
|
||||
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nread));
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nread), true);
|
||||
goto free;
|
||||
}
|
||||
|
||||
|
|
@ -903,7 +917,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||
REQUIRE(VALID_NMSOCK(ssock));
|
||||
REQUIRE(ssock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(ssock)) {
|
||||
if (isc__nmsocket_closing(ssock)) {
|
||||
if (quota != NULL) {
|
||||
isc_quota_detach("a);
|
||||
}
|
||||
|
|
@ -1097,7 +1111,7 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
UNUSED(worker);
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1167,11 +1181,7 @@ tcpdns_stop_cb(uv_handle_t *handle) {
|
|||
}
|
||||
|
||||
static void
|
||||
tcpdns_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
tcpdns_close_sock(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->closing));
|
||||
|
|
@ -1194,12 +1204,25 @@ tcpdns_close_cb(uv_handle_t *handle) {
|
|||
}
|
||||
|
||||
static void
|
||||
timer_close_cb(uv_handle_t *handle) {
|
||||
tcpdns_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
tcpdns_close_sock(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
timer_close_cb(uv_handle_t *timer) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(timer);
|
||||
uv_handle_set_data(timer, NULL);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
if (sock->parent) {
|
||||
uv_close(&sock->uv_handle.handle, tcpdns_stop_cb);
|
||||
} else if (uv_is_closing(&sock->uv_handle.handle)) {
|
||||
tcpdns_close_sock(sock);
|
||||
} else {
|
||||
uv_close(&sock->uv_handle.handle, tcpdns_close_cb);
|
||||
}
|
||||
|
|
@ -1271,6 +1294,8 @@ tcpdns_close_direct(isc_nmsocket_t *sock) {
|
|||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
uv_close((uv_handle_t *)&sock->timer, timer_close_cb);
|
||||
}
|
||||
|
||||
|
|
@ -1313,6 +1338,19 @@ isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
tcpdns_close_direct(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
tcpdns_close_connect_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tcpdns_shutdown(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -1327,12 +1365,19 @@ isc__nm_tcpdns_shutdown(isc_nmsocket_t *sock) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (atomic_load(&sock->connecting) || sock->accepting) {
|
||||
if (sock->accepting) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
if (atomic_load(&sock->connecting)) {
|
||||
isc_nmsocket_t *tsock = NULL;
|
||||
isc__nmsocket_attach(sock, &tsock);
|
||||
uv_close(&sock->uv_handle.handle, tcpdns_close_connect_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle != NULL) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1372,7 +1417,7 @@ isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -110,6 +110,10 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
|
||||
atomic_store(&sock->connecting, true);
|
||||
|
||||
/* 2 minute timeout */
|
||||
result = isc__nm_socket_connectiontimeout(sock->fd, 120 * 1000);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
r = uv_tcp_init(&worker->loop, &sock->uv_handle.tcp);
|
||||
RUNTIME_CHECK(r == 0);
|
||||
uv_handle_set_data(&sock->uv_handle.handle, sock);
|
||||
|
|
@ -118,6 +122,11 @@ tlsdns_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);
|
||||
|
|
@ -149,11 +158,14 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
}
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]);
|
||||
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, &req->uv_req.connect);
|
||||
isc__nmsocket_timer_start(sock);
|
||||
|
||||
atomic_store(&sock->connected, true);
|
||||
|
||||
done:
|
||||
result = isc__nm_uverr2result(r);
|
||||
|
||||
error:
|
||||
LOCK(&sock->lock);
|
||||
sock->result = result;
|
||||
SIGNAL(&sock->cond);
|
||||
|
|
@ -184,9 +196,12 @@ isc__nm_async_tlsdnsconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
result = tlsdns_connect_direct(sock, req);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(atomic_compare_exchange_strong(&sock->connecting,
|
||||
&(bool){ true }, false));
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -205,20 +220,25 @@ tlsdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->connecting));
|
||||
|
||||
if (!atomic_load(&sock->connecting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
req = uv_handle_get_data((uv_handle_t *)uvreq);
|
||||
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
REQUIRE(VALID_NMHANDLE(req->handle));
|
||||
|
||||
/* Socket was closed midflight by isc__nm_tlsdns_shutdown() */
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
/* Socket was closed midflight by isc__nm_tlsdns_shutdown() */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
} else if (status == UV_ETIMEDOUT) {
|
||||
/* Timeout status code here indicates hard error */
|
||||
result = ISC_R_CANCELED;
|
||||
goto error;
|
||||
} else if (status != 0) {
|
||||
result = isc__nm_uverr2result(status);
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -248,10 +268,11 @@ tlsdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
|
||||
#if HAVE_SSL_SET0_RBIO && HAVE_SSL_SET0_WBIO
|
||||
/*
|
||||
* Note that if the rbio and wbio are the same then SSL_set0_rbio() and
|
||||
* SSL_set0_wbio() each take ownership of one reference. Therefore it
|
||||
* may be necessary to increment the number of references available
|
||||
* using BIO_up_ref(3) before calling the set0 functions.
|
||||
* Note that if the rbio and wbio are the same then
|
||||
* SSL_set0_rbio() and SSL_set0_wbio() each take ownership of
|
||||
* one reference. Therefore it may be necessary to increment the
|
||||
* number of references available using BIO_up_ref(3) before
|
||||
* calling the set0 functions.
|
||||
*/
|
||||
SSL_set0_rbio(sock->tls.tls, sock->tls.ssl_rbio);
|
||||
SSL_set0_wbio(sock->tls.tls, sock->tls.ssl_wbio);
|
||||
|
|
@ -264,23 +285,24 @@ tlsdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
/* Setting pending req */
|
||||
sock->tls.pending_req = req;
|
||||
|
||||
isc__nm_process_sock_buffer(sock);
|
||||
|
||||
result = tls_cycle(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
sock->tls.pending_req = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
sock->tls.pending_req = NULL;
|
||||
isc__nm_failed_connect_cb(sock, req, result);
|
||||
isc__nm_failed_connect_cb(sock, req, result, false);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -289,7 +311,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);
|
||||
|
|
@ -298,28 +319,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, timeout);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
atomic_init(&sock->connecting, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
req->cb.connect = cb;
|
||||
|
|
@ -328,6 +336,19 @@ 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) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (isc__nm_closing(sock)) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* 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()) {
|
||||
|
|
@ -343,17 +364,24 @@ 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;
|
||||
failure:
|
||||
if (isc__nm_in_netthread()) {
|
||||
sock->tid = isc_nm_tid();
|
||||
}
|
||||
|
||||
return (result);
|
||||
INSIST(atomic_compare_exchange_strong(&sock->connecting,
|
||||
&(bool){ true }, false));
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_connectcb(sock, req, result, true);
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
static uv_os_sock_t
|
||||
|
|
@ -552,8 +580,9 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
#endif
|
||||
|
||||
/*
|
||||
* The callback will run in the same thread uv_listen() was called
|
||||
* from, so a race with tlsdns_connection_cb() isn't possible.
|
||||
* The callback will run in the same thread uv_listen() was
|
||||
* called from, so a race with tlsdns_connection_cb() isn't
|
||||
* possible.
|
||||
*/
|
||||
r = uv_listen((uv_stream_t *)&sock->uv_handle.tcp, sock->backlog,
|
||||
tlsdns_connection_cb);
|
||||
|
|
@ -600,7 +629,7 @@ tlsdns_connection_cb(uv_stream_t *server, int status) {
|
|||
REQUIRE(VALID_NMSOCK(ssock));
|
||||
REQUIRE(ssock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(ssock)) {
|
||||
if (isc__nmsocket_closing(ssock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -742,7 +771,8 @@ isc__nm_async_tlsdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
}
|
||||
|
||||
/*
|
||||
* If network manager is interlocked, re-enqueue the event for later.
|
||||
* If network manager is interlocked, re-enqueue the event for
|
||||
* later.
|
||||
*/
|
||||
if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
||||
enqueue_stoplistening(sock);
|
||||
|
|
@ -753,7 +783,8 @@ isc__nm_async_tlsdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
}
|
||||
|
||||
void
|
||||
isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
||||
isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
||||
bool async) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(result != ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -763,7 +794,7 @@ isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
if (sock->tls.pending_req != NULL) {
|
||||
isc__nm_uvreq_t *req = sock->tls.pending_req;
|
||||
sock->tls.pending_req = NULL;
|
||||
isc__nm_failed_connect_cb(sock, req, ISC_R_CANCELED);
|
||||
isc__nm_failed_connect_cb(sock, req, ISC_R_CANCELED, async);
|
||||
}
|
||||
|
||||
if (!sock->recv_read) {
|
||||
|
|
@ -780,8 +811,8 @@ isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
destroy:
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
|
||||
/* We need to detach from quota after the read callback function had a
|
||||
* chance to be executed. */
|
||||
/* We need to detach from quota after the read callback function
|
||||
* had a chance to be executed. */
|
||||
if (sock->quota) {
|
||||
isc_quota_detach(&sock->quota);
|
||||
}
|
||||
|
|
@ -813,10 +844,11 @@ isc__nm_tlsdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
|||
ievent = isc__nm_get_netievent_tlsdnsread(sock->mgr, sock);
|
||||
|
||||
/*
|
||||
* This MUST be done asynchronously, no matter which thread we're
|
||||
* in. The callback function for isc_nm_read() often calls
|
||||
* This MUST be done asynchronously, no matter which thread
|
||||
* we're in. The callback function for isc_nm_read() often calls
|
||||
* isc_nm_read() again; if we tried to do that synchronously
|
||||
* we'd clash in processbuffer() and grow the stack indefinitely.
|
||||
* we'd clash in processbuffer() and grow the stack
|
||||
* indefinitely.
|
||||
*/
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
|
|
@ -836,15 +868,15 @@ isc__nm_async_tlsdnsread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
result = tls_cycle(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc__nm_failed_read_cb(sock, result);
|
||||
isc__nm_failed_read_cb(sock, result, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -866,7 +898,7 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
|
|
@ -892,7 +924,8 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
|
|||
|
||||
/*
|
||||
* We need to launch the resume_processing after the buffer has
|
||||
* been consumed, thus we need to delay the detaching the handle.
|
||||
* been consumed, thus we need to delay the detaching the
|
||||
* handle.
|
||||
*/
|
||||
isc_nmhandle_attach(req->handle, &handle);
|
||||
|
||||
|
|
@ -905,15 +938,16 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
|
|||
req->uvbuf.len = len;
|
||||
|
||||
/*
|
||||
* If isc__nm_tlsdns_read() was called, it will be satisfied by single
|
||||
* DNS message in the next call.
|
||||
* If isc__nm_tlsdns_read() was called, it will be satisfied by
|
||||
* single DNS message in the next call.
|
||||
*/
|
||||
sock->recv_read = false;
|
||||
|
||||
/*
|
||||
* The assertion failure here means that there's a errnoneous extra
|
||||
* nmhandle detach happening in the callback and resume_processing gets
|
||||
* called while we are still processing the buffer.
|
||||
* The assertion failure here means that there's a errnoneous
|
||||
* extra nmhandle detach happening in the callback and
|
||||
* resume_processing gets called while we are still processing
|
||||
* the buffer.
|
||||
*/
|
||||
REQUIRE(sock->processing == false);
|
||||
sock->processing = true;
|
||||
|
|
@ -958,14 +992,19 @@ tls_cycle_input(isc_nmsocket_t *sock) {
|
|||
sock->buf + sock->buf_len,
|
||||
sock->buf_size - sock->buf_len, &len);
|
||||
if (rv != 1) {
|
||||
/* Process what's in the buffer so far */
|
||||
/*
|
||||
* Process what's in the buffer so far
|
||||
*/
|
||||
isc__nm_process_sock_buffer(sock);
|
||||
|
||||
/* FIXME: Should we call failed_read_cb()? */
|
||||
/*
|
||||
* FIXME: Should we call
|
||||
* isc__nm_failed_read_cb()?
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
REQUIRE((size_t)pending == len);
|
||||
INSIST((size_t)pending == len);
|
||||
|
||||
sock->buf_len += len;
|
||||
|
||||
|
|
@ -1030,9 +1069,12 @@ tls_cycle_input(isc_nmsocket_t *sock) {
|
|||
isc__nm_uvreq_t *req = sock->tls.pending_req;
|
||||
sock->tls.pending_req = NULL;
|
||||
|
||||
atomic_store(&sock->connecting, false);
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS);
|
||||
INSIST(atomic_compare_exchange_strong(
|
||||
&sock->connecting, &(bool){ true }, false));
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS, true);
|
||||
}
|
||||
async_tlsdns_cycle(sock);
|
||||
}
|
||||
|
|
@ -1045,7 +1087,14 @@ tls_error(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
switch (sock->tls.state) {
|
||||
case TLS_STATE_HANDSHAKE:
|
||||
case TLS_STATE_IO:
|
||||
isc__nm_tlsdns_failed_read_cb(sock, result);
|
||||
if (atomic_load(&sock->connecting)) {
|
||||
isc__nm_uvreq_t *req = sock->tls.pending_req;
|
||||
sock->tls.pending_req = NULL;
|
||||
|
||||
isc__nm_failed_connect_cb(sock, req, result, false);
|
||||
} else {
|
||||
isc__nm_tlsdns_failed_read_cb(sock, result, false);
|
||||
}
|
||||
break;
|
||||
case TLS_STATE_ERROR:
|
||||
return;
|
||||
|
|
@ -1056,7 +1105,7 @@ tls_error(isc_nmsocket_t *sock, isc_result_t result) {
|
|||
sock->tls.state = TLS_STATE_ERROR;
|
||||
sock->tls.pending_error = result;
|
||||
|
||||
/* tlsdns_close_direct(sock); */
|
||||
isc__nmsocket_shutdown(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1141,7 +1190,8 @@ tls_cycle_output(isc_nmsocket_t *sock) {
|
|||
req->uvbuf.len - err);
|
||||
req->uvbuf.len = req->uvbuf.len - err;
|
||||
} else if (err == UV_ENOSYS || err == UV_EAGAIN) {
|
||||
/* uv_try_write is not supported, send asynchronously */
|
||||
/* uv_try_write is not supported, send
|
||||
* asynchronously */
|
||||
} else {
|
||||
result = isc__nm_uverr2result(err);
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
|
|
@ -1182,6 +1232,10 @@ static isc_result_t
|
|||
tls_cycle(isc_nmsocket_t *sock) {
|
||||
isc_result_t result;
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
result = tls_pop_error(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto done;
|
||||
|
|
@ -1212,7 +1266,7 @@ async_tlsdns_cycle(isc_nmsocket_t *sock) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
/* Socket was closed midflight by isc__nm_tlsdns_shutdown() */
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1255,8 +1309,8 @@ isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||
REQUIRE(sock->reading);
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, true);
|
||||
goto free;
|
||||
}
|
||||
|
||||
|
|
@ -1266,7 +1320,7 @@ isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||
sock->statsindex[STATID_RECVFAIL]);
|
||||
}
|
||||
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nread));
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nread), true);
|
||||
|
||||
goto free;
|
||||
}
|
||||
|
|
@ -1281,13 +1335,13 @@ isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread,
|
|||
rv = BIO_write_ex(sock->tls.app_wbio, buf->base, (size_t)nread, &len);
|
||||
|
||||
if (rv <= 0 || (size_t)nread != len) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_TLSERROR);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_TLSERROR, true);
|
||||
goto free;
|
||||
}
|
||||
|
||||
result = tls_cycle(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc__nm_failed_read_cb(sock, result);
|
||||
isc__nm_failed_read_cb(sock, result, true);
|
||||
}
|
||||
free:
|
||||
async_tlsdns_cycle(sock);
|
||||
|
|
@ -1301,7 +1355,8 @@ quota_accept_cb(isc_quota_t *quota, void *sock0) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
/*
|
||||
* Create a tlsdnsaccept event and pass it using the async channel.
|
||||
* Create a tlsdnsaccept event and pass it using the async
|
||||
* channel.
|
||||
*/
|
||||
|
||||
isc__netievent_tlsdnsaccept_t *ievent =
|
||||
|
|
@ -1351,7 +1406,7 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||
REQUIRE(VALID_NMSOCK(ssock));
|
||||
REQUIRE(ssock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(ssock)) {
|
||||
if (isc__nmsocket_closing(ssock)) {
|
||||
if (quota != NULL) {
|
||||
isc_quota_detach("a);
|
||||
}
|
||||
|
|
@ -1418,8 +1473,8 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||
}
|
||||
|
||||
/*
|
||||
* The handle will be either detached on acceptcb failure or in the
|
||||
* readcb.
|
||||
* The handle will be either detached on acceptcb failure or in
|
||||
* the readcb.
|
||||
*/
|
||||
handle = isc__nmhandle_get(csock, NULL, &local);
|
||||
|
||||
|
|
@ -1444,10 +1499,11 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||
|
||||
#if HAVE_SSL_SET0_RBIO && HAVE_SSL_SET0_WBIO
|
||||
/*
|
||||
* Note that if the rbio and wbio are the same then SSL_set0_rbio() and
|
||||
* SSL_set0_wbio() each take ownership of one reference. Therefore it
|
||||
* may be necessary to increment the number of references available
|
||||
* using BIO_up_ref(3) before calling the set0 functions.
|
||||
* Note that if the rbio and wbio are the same then
|
||||
* SSL_set0_rbio() and SSL_set0_wbio() each take ownership of
|
||||
* one reference. Therefore it may be necessary to increment the
|
||||
* number of references available using BIO_up_ref(3) before
|
||||
* calling the set0 functions.
|
||||
*/
|
||||
SSL_set0_rbio(csock->tls.tls, csock->tls.ssl_rbio);
|
||||
SSL_set0_wbio(csock->tls.tls, csock->tls.ssl_wbio);
|
||||
|
|
@ -1468,15 +1524,15 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
|
|||
csock->closehandle_cb = isc__nm_resume_processing;
|
||||
|
||||
/*
|
||||
* We need to keep the handle alive until we fail to read or connection
|
||||
* is closed by the other side, it will be detached via
|
||||
* prep_destroy()->tlsdns_close_direct().
|
||||
* We need to keep the handle alive until we fail to read or
|
||||
* connection is closed by the other side, it will be detached
|
||||
* via prep_destroy()->tlsdns_close_direct().
|
||||
*/
|
||||
isc_nmhandle_attach(handle, &csock->recv_handle);
|
||||
|
||||
/*
|
||||
* The initial timer has been set, update the read timeout for the next
|
||||
* reads.
|
||||
* The initial timer has been set, update the read timeout for
|
||||
* the next reads.
|
||||
*/
|
||||
csock->read_timeout = (atomic_load(&csock->keepalive)
|
||||
? atomic_load(&csock->mgr->keepalive)
|
||||
|
|
@ -1583,7 +1639,7 @@ tlsdns_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
|
|
@ -1593,8 +1649,8 @@ tlsdns_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
}
|
||||
|
||||
/*
|
||||
* There's no SSL_writev(), so we need to use a local buffer to assemble
|
||||
* the whole message
|
||||
* There's no SSL_writev(), so we need to use a local buffer to
|
||||
* assemble the whole message
|
||||
*/
|
||||
worker = &sock->mgr->workers[sock->tid];
|
||||
sendlen = req->uvbuf.len + sizeof(uint16_t);
|
||||
|
|
@ -1664,10 +1720,7 @@ tlsdns_stop_cb(uv_handle_t *handle) {
|
|||
}
|
||||
|
||||
static void
|
||||
tlsdns_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
tlsdns_close_sock(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->closing));
|
||||
|
|
@ -1698,14 +1751,25 @@ tlsdns_close_cb(uv_handle_t *handle) {
|
|||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
tlsdns_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
tlsdns_close_sock(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
timer_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
||||
uv_handle_set_data(handle, NULL);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
if (sock->parent) {
|
||||
uv_close(&sock->uv_handle.handle, tlsdns_stop_cb);
|
||||
} else if (uv_is_closing(&sock->uv_handle.handle)) {
|
||||
tlsdns_close_sock(sock);
|
||||
} else {
|
||||
uv_close(&sock->uv_handle.handle, tlsdns_close_cb);
|
||||
}
|
||||
|
|
@ -1780,6 +1844,8 @@ tlsdns_close_direct(isc_nmsocket_t *sock) {
|
|||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
|
||||
uv_close((uv_handle_t *)&sock->timer, timer_close_cb);
|
||||
}
|
||||
|
||||
|
|
@ -1798,7 +1864,8 @@ isc__nm_tlsdns_close(isc_nmsocket_t *sock) {
|
|||
tlsdns_close_direct(sock);
|
||||
} else {
|
||||
/*
|
||||
* We need to create an event and pass it using async channel
|
||||
* We need to create an event and pass it using async
|
||||
* channel
|
||||
*/
|
||||
isc__netievent_tlsdnsclose_t *ievent =
|
||||
isc__nm_get_netievent_tlsdnsclose(sock->mgr, sock);
|
||||
|
|
@ -1822,6 +1889,19 @@ isc__nm_async_tlsdnsclose(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
tlsdns_close_direct(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
tlsdns_close_connect_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tlsdns_shutdown(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -1836,18 +1916,39 @@ isc__nm_tlsdns_shutdown(isc_nmsocket_t *sock) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (sock->tls.pending_req != NULL) {
|
||||
isc__nm_uvreq_t *req = sock->tls.pending_req;
|
||||
sock->tls.pending_req = NULL;
|
||||
isc__nm_failed_connect_cb(sock, req, ISC_R_CANCELED);
|
||||
if (sock->tls.tls) {
|
||||
/* Shutdown any active TLS connections */
|
||||
(void)SSL_shutdown(sock->tls.tls);
|
||||
}
|
||||
|
||||
if (atomic_load(&sock->connecting) || sock->accepting) {
|
||||
if (sock->accepting) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
/* TLS handshake hasn't been completed yet */
|
||||
if (atomic_load(&sock->connecting)) {
|
||||
/*
|
||||
* TCP connection has been established, now waiting on
|
||||
* TLS handshake to complete
|
||||
*/
|
||||
if (sock->tls.pending_req != NULL) {
|
||||
isc__nm_uvreq_t *req = sock->tls.pending_req;
|
||||
sock->tls.pending_req = NULL;
|
||||
|
||||
isc__nm_failed_connect_cb(sock, req, ISC_R_CANCELED,
|
||||
false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The TCP connection hasn't been established yet */
|
||||
isc_nmsocket_t *tsock = NULL;
|
||||
isc__nmsocket_attach(sock, &tsock);
|
||||
uv_close(&sock->uv_handle.handle, tlsdns_close_connect_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock->statichandle != NULL) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1887,7 +1988,7 @@ isc__nm_async_tlsdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
|||
* we can free the buffer and bail.
|
||||
*/
|
||||
if (addr == NULL) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF, false);
|
||||
goto free;
|
||||
}
|
||||
|
||||
|
|
@ -391,12 +391,13 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
|||
* - If the socket is no longer active.
|
||||
*/
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
goto free;
|
||||
}
|
||||
|
||||
if (nrecv < 0) {
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nrecv));
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nrecv),
|
||||
false);
|
||||
goto free;
|
||||
}
|
||||
|
||||
|
|
@ -523,7 +524,7 @@ isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
UNUSED(worker);
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
isc__nm_failed_send_cb(sock, uvreq, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
|
@ -567,7 +568,7 @@ udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
|
|
@ -597,6 +598,7 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
isc__networker_t *worker = NULL;
|
||||
int uv_bind_flags = UV_UDP_REUSEADDR;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
int tries = 3;
|
||||
int r;
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
|
|
@ -616,7 +618,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;
|
||||
}
|
||||
|
|
@ -642,7 +643,15 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
&(int){ ISC_SEND_BUFFER_SIZE });
|
||||
#endif
|
||||
|
||||
r = isc_uv_udp_connect(&sock->uv_handle.udp, &req->peer.type.sa);
|
||||
/*
|
||||
* On FreeBSD the UDP connect() call sometimes results in a
|
||||
* spurious transient EADDRINUSE. Try a few more times before
|
||||
* giving up.
|
||||
*/
|
||||
do {
|
||||
r = isc_uv_udp_connect(&sock->uv_handle.udp,
|
||||
&req->peer.type.sa);
|
||||
} while (r == UV_EADDRINUSE && --tries > 0);
|
||||
if (r != 0) {
|
||||
isc__nm_incstats(sock->mgr,
|
||||
sock->statsindex[STATID_CONNECTFAIL]);
|
||||
|
|
@ -693,13 +702,13 @@ 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
|
||||
* initialized
|
||||
*/
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS);
|
||||
isc__nm_connectcb(sock, req, ISC_R_SUCCESS, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -708,7 +717,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) {
|
||||
|
|
@ -717,7 +726,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);
|
||||
|
|
@ -725,15 +733,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);
|
||||
|
||||
|
|
@ -742,10 +741,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);
|
||||
|
|
@ -758,12 +774,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()) {
|
||||
|
|
@ -779,17 +789,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
|
||||
|
|
@ -868,9 +873,9 @@ isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (isc__nm_inactive(sock)) {
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
sock->reading = true;
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1084,8 +1089,8 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock) {
|
|||
* sock->statichandle would be NULL, in that case, nobody is
|
||||
* interested in the callback.
|
||||
*/
|
||||
if (sock->statichandle) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
if (sock->statichandle != NULL) {
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1129,5 +1134,5 @@ isc__nm_async_udpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->client));
|
||||
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,8 @@ static bool skip_long_tests = false;
|
|||
#define T_ADVERTISED 120 * 1000
|
||||
#define T_CONNECT 30 * 1000
|
||||
|
||||
#define WAIT_REPEATS 100
|
||||
/* Wait for 1 second (1000 * 1000 microseconds) */
|
||||
#define WAIT_REPEATS 1000
|
||||
#define T_WAIT 1000 /* In microseconds */
|
||||
|
||||
#define WAIT_FOR(v, op, val) \
|
||||
|
|
@ -191,18 +192,29 @@ _setup(void **state __attribute__((unused))) {
|
|||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (getenv("CI_ENABLE_ALL_TESTS") != NULL) {
|
||||
if (getenv("CI") == NULL || getenv("CI_ENABLE_ALL_TESTS") != NULL) {
|
||||
esends = NSENDS * workers;
|
||||
} else {
|
||||
esends = workers;
|
||||
skip_long_tests = true;
|
||||
}
|
||||
|
||||
if (isc_tlsctx_createserver(NULL, NULL, &tcp_listen_tlsctx) !=
|
||||
ISC_R_SUCCESS) {
|
||||
return (-1);
|
||||
}
|
||||
if (isc_tlsctx_createclient(&tcp_connect_tlsctx) != ISC_R_SUCCESS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
_teardown(void **state __attribute__((unused))) {
|
||||
isc_tlsctx_free(&tcp_connect_tlsctx);
|
||||
isc_tlsctx_free(&tcp_listen_tlsctx);
|
||||
|
||||
isc_test_end();
|
||||
|
||||
return (0);
|
||||
|
|
@ -279,14 +291,6 @@ nm_setup(void **state __attribute__((unused))) {
|
|||
isc__nm_closesocket(tcp_listen_sock);
|
||||
tcp_listen_sock = -1;
|
||||
|
||||
if (isc_tlsctx_createserver(NULL, NULL, &tcp_listen_tlsctx) !=
|
||||
ISC_R_SUCCESS) {
|
||||
return (-1);
|
||||
}
|
||||
if (isc_tlsctx_createclient(&tcp_connect_tlsctx) != ISC_R_SUCCESS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
atomic_store(&do_send, true);
|
||||
atomic_store(&nsends, esends);
|
||||
|
||||
|
|
@ -330,27 +334,24 @@ static int
|
|||
nm_teardown(void **state __attribute__((unused))) {
|
||||
UNUSED(state);
|
||||
|
||||
WAIT_FOR_EQ(active_cconnects, 0);
|
||||
WAIT_FOR_EQ(active_csends, 0);
|
||||
WAIT_FOR_EQ(active_csends, 0);
|
||||
WAIT_FOR_EQ(active_ssends, 0);
|
||||
WAIT_FOR_EQ(active_sreads, 0);
|
||||
|
||||
isc_nm_destroy(&connect_nm);
|
||||
assert_null(connect_nm);
|
||||
|
||||
isc_nm_destroy(&listen_nm);
|
||||
assert_null(listen_nm);
|
||||
|
||||
WAIT_FOR_EQ(active_cconnects, 0);
|
||||
WAIT_FOR_EQ(active_csends, 0);
|
||||
WAIT_FOR_EQ(active_csends, 0);
|
||||
WAIT_FOR_EQ(active_ssends, 0);
|
||||
WAIT_FOR_EQ(active_sreads, 0);
|
||||
|
||||
isc_refcount_destroy(&active_cconnects);
|
||||
isc_refcount_destroy(&active_csends);
|
||||
isc_refcount_destroy(&active_creads);
|
||||
isc_refcount_destroy(&active_ssends);
|
||||
isc_refcount_destroy(&active_sreads);
|
||||
|
||||
isc_tlsctx_free(&tcp_connect_tlsctx);
|
||||
isc_tlsctx_free(&tcp_listen_tlsctx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -456,12 +457,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 +475,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,12 +565,11 @@ 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 };
|
||||
|
|
@ -578,26 +578,15 @@ connect_thread(isc_threadarg_t arg) {
|
|||
while (atomic_load(&do_send)) {
|
||||
uint_fast32_t active =
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
if (active >= workers) {
|
||||
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 +594,11 @@ 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_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 +648,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 +661,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 +675,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 +689,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 +702,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 +726,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 +748,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 +785,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 +826,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 +1053,11 @@ 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_nm_tcpconnect(nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 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, T_CONNECT, 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, T_CONNECT, 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,11 @@ 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_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 +1486,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 +1513,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 +1551,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 +1592,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 +1821,12 @@ 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_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 +1844,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 +1873,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 +1914,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 +1958,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,13 +66,23 @@ static atomic_uint_fast64_t csends;
|
|||
static atomic_uint_fast64_t creads;
|
||||
static atomic_uint_fast64_t ctimeouts;
|
||||
|
||||
static unsigned int workers = 0;
|
||||
static atomic_bool slowdown = ATOMIC_VAR_INIT(false);
|
||||
|
||||
static bool reuse_supported = true;
|
||||
static unsigned int workers = 0;
|
||||
|
||||
static isc_tlsctx_t *server_tlsctx = NULL;
|
||||
static isc_tlsctx_t *client_tlsctx = NULL;
|
||||
|
||||
static atomic_bool was_error = ATOMIC_VAR_INIT(false);
|
||||
|
||||
static bool skip_long_tests = false;
|
||||
|
||||
#define SKIP_IN_CI \
|
||||
if (skip_long_tests) { \
|
||||
skip(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define NSENDS 100
|
||||
#define NWRITES 10
|
||||
|
||||
|
|
@ -145,9 +155,6 @@ setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) {
|
|||
close(fd);
|
||||
return (-1);
|
||||
}
|
||||
if (result == ISC_R_NOTIMPLEMENTED) {
|
||||
reuse_supported = false;
|
||||
}
|
||||
|
||||
#if IPV6_RECVERR
|
||||
#define setsockopt_on(socket, level, name) \
|
||||
|
|
@ -185,6 +192,10 @@ _setup(void **state) {
|
|||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (getenv("CI") != NULL && getenv("CI_ENABLE_ALL_TESTS") == NULL) {
|
||||
skip_long_tests = true;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -241,6 +252,8 @@ nm_setup(void **state) {
|
|||
atomic_store(&ctimeouts, 0);
|
||||
atomic_store(&cconnects, 0);
|
||||
|
||||
atomic_store(&was_error, false);
|
||||
|
||||
isc_nonce_buf(&send_magic, sizeof(send_magic));
|
||||
isc_nonce_buf(&stop_magic, sizeof(stop_magic));
|
||||
if (send_magic == stop_magic) {
|
||||
|
|
@ -389,6 +402,8 @@ 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);
|
||||
atomic_store(&was_error, true);
|
||||
|
||||
/* We failed to connect; try again */
|
||||
while (sends > 0) {
|
||||
|
|
@ -431,10 +446,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 +476,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 +492,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,12 +533,14 @@ 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) {
|
||||
if (atomic_load(&was_error)) {
|
||||
break;
|
||||
}
|
||||
isc_thread_yield();
|
||||
}
|
||||
|
||||
|
|
@ -531,6 +548,9 @@ tls_recv_one(void **state) {
|
|||
atomic_load(&sreads) != 1 || atomic_load(&creads) != 0 ||
|
||||
atomic_load(&csends) != 1)
|
||||
{
|
||||
if (atomic_load(&was_error)) {
|
||||
break;
|
||||
}
|
||||
isc_thread_yield();
|
||||
}
|
||||
|
||||
|
|
@ -573,19 +593,24 @@ 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) {
|
||||
if (atomic_load(&was_error)) {
|
||||
break;
|
||||
}
|
||||
isc_thread_yield();
|
||||
}
|
||||
|
||||
while (atomic_load(&sreads) < 2 || atomic_load(&ssends) < 1 ||
|
||||
atomic_load(&csends) < 2 || atomic_load(&creads) < 1)
|
||||
{
|
||||
if (atomic_load(&was_error)) {
|
||||
break;
|
||||
}
|
||||
isc_thread_yield();
|
||||
}
|
||||
|
||||
|
|
@ -619,10 +644,7 @@ tls_recv_send(void **state) {
|
|||
size_t nthreads = ISC_MAX(ISC_MIN(workers, 32), 1);
|
||||
isc_thread_t threads[32] = { 0 };
|
||||
|
||||
if (!reuse_supported) {
|
||||
skip();
|
||||
return;
|
||||
}
|
||||
SKIP_IN_CI;
|
||||
|
||||
result = isc_nm_listentls(listen_nm, (isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_listen_accept_cb, NULL, 0, 0, NULL,
|
||||
|
|
@ -665,10 +687,7 @@ tls_recv_half_send(void **state) {
|
|||
size_t nthreads = ISC_MAX(ISC_MIN(workers, 32), 1);
|
||||
isc_thread_t threads[32] = { 0 };
|
||||
|
||||
if (!reuse_supported) {
|
||||
skip();
|
||||
return;
|
||||
}
|
||||
SKIP_IN_CI;
|
||||
|
||||
result = isc_nm_listentls(listen_nm, (isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_listen_accept_cb, NULL, 0, 0, NULL,
|
||||
|
|
@ -716,10 +735,7 @@ tls_half_recv_send(void **state) {
|
|||
size_t nthreads = ISC_MAX(ISC_MIN(workers, 32), 1);
|
||||
isc_thread_t threads[32] = { 0 };
|
||||
|
||||
if (!reuse_supported) {
|
||||
skip();
|
||||
return;
|
||||
}
|
||||
SKIP_IN_CI;
|
||||
|
||||
result = isc_nm_listentls(listen_nm, (isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_listen_accept_cb, NULL, 0, 0, NULL,
|
||||
|
|
@ -767,10 +783,7 @@ tls_half_recv_half_send(void **state) {
|
|||
size_t nthreads = ISC_MAX(ISC_MIN(workers, 32), 1);
|
||||
isc_thread_t threads[32] = { 0 };
|
||||
|
||||
if (!reuse_supported) {
|
||||
skip();
|
||||
return;
|
||||
}
|
||||
SKIP_IN_CI;
|
||||
|
||||
result = isc_nm_listentls(listen_nm, (isc_nmiface_t *)&tls_listen_addr,
|
||||
tls_listen_accept_cb, NULL, 0, 0, NULL,
|
||||
|
|
|
|||
|
|
@ -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