2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

Merge branch '3200-add-per-send-timer' into 'main'

Change single write timer to per-send timers

Closes #3200

See merge request isc-projects/bind9!5955
This commit is contained in:
Ondřej Surý
2022-03-11 09:39:58 +00:00
10 changed files with 132 additions and 204 deletions

View File

@@ -1,3 +1,6 @@
5828. [bug] Replace single TCP write timer with per-TCP write
timers. [GL #3200]
5827. [cleanup] The command-line utilities printed their version numbers 5827. [cleanup] The command-line utilities printed their version numbers
inconsistently; they all now print to stdout. (They are inconsistently; they all now print to stdout. (They are
still inconsistent abotut whether you use `-v` or `-V` still inconsistent abotut whether you use `-v` or `-V`
@@ -6,7 +9,7 @@
5826. [cleanup] Stop dig from complaining about lack of IDN support when 5826. [cleanup] Stop dig from complaining about lack of IDN support when
the user asks for no IDN translation. [GL #3188] the user asks for no IDN translation. [GL #3188]
5825. [funcf] Set the minimum MTU on UDPv6 and TCPv6 sockets and 5825. [func] Set the minimum MTU on UDPv6 and TCPv6 sockets and
limit TCP maximum segment size (TCP_MAXSEG) to (1220) limit TCP maximum segment size (TCP_MAXSEG) to (1220)
for both TCPv4 and TCPv6 sockets. [GL #2201] for both TCPv4 and TCPv6 sockets. [GL #2201]

View File

@@ -106,3 +106,7 @@ Bug Fixes
algorithm. This is now checked for and the dnssec-policy is algorithm. This is now checked for and the dnssec-policy is
rejected if both roles are not present for all algorithms in use. rejected if both roles are not present for all algorithms in use.
:gl:`#3142` :gl:`#3142`
- Handling of the TCP write timeouts has been improved to track timeout
for each TCP write separately leading to faster connection tear down
in case the other party is not reading the data. :gl:`#3200`

View File

@@ -700,7 +700,7 @@ new_httpd(isc_httpdmgr_t *httpdmgr, isc_nmhandle_t *handle) {
ISC_LIST_APPEND(httpdmgr->running, httpd, link); ISC_LIST_APPEND(httpdmgr->running, httpd, link);
UNLOCK(&httpdmgr->lock); UNLOCK(&httpdmgr->lock);
isc_nmhandle_attach(handle, &httpd->readhandle); isc_nmhandle_attach(httpd->handle, &httpd->readhandle);
isc_nm_read(handle, httpd_request, httpdmgr); isc_nm_read(handle, httpd_request, httpdmgr);
} }
@@ -869,6 +869,7 @@ httpd_request(isc_nmhandle_t *handle, isc_result_t eresult,
httpd = isc_nmhandle_getdata(handle); httpd = isc_nmhandle_getdata(handle);
REQUIRE(httpd->state == RECV); REQUIRE(httpd->state == RECV);
REQUIRE(httpd->handle == handle);
if (eresult != ISC_R_SUCCESS) { if (eresult != ISC_R_SUCCESS) {
goto cleanup_readhandle; goto cleanup_readhandle;
@@ -883,13 +884,13 @@ httpd_request(isc_nmhandle_t *handle, isc_result_t eresult,
/* don't unref, keep reading */ /* don't unref, keep reading */
return; return;
} }
/* /*
* We have been called from httpd_senddone * We must have been called from httpd_senddone (as
* and we need to resume reading. Detach * ISC_R_NOTFOUND is not returned from netmgr) and we
* readhandle before resuming. * need to resume reading.
*/ */
isc_nmhandle_detach(&httpd->readhandle); isc_nm_resumeread(httpd->readhandle);
isc_nm_resumeread(handle);
return; return;
} }
goto cleanup_readhandle; goto cleanup_readhandle;
@@ -1002,11 +1003,12 @@ httpd_request(isc_nmhandle_t *handle, isc_result_t eresult,
*/ */
isc_buffer_usedregion(httpd->sendbuffer, &r); isc_buffer_usedregion(httpd->sendbuffer, &r);
isc_nm_pauseread(handle); isc_nm_pauseread(httpd->handle);
httpd->state = SEND; httpd->state = SEND;
isc_nmhandle_attach(handle, &httpd->sendhandle); isc_nmhandle_attach(httpd->handle, &httpd->sendhandle);
isc_nm_send(handle, &r, httpd_senddone, httpd); isc_nm_send(httpd->sendhandle, &r, httpd_senddone, httpd);
return;
cleanup_readhandle: cleanup_readhandle:
isc_nmhandle_detach(&httpd->readhandle); isc_nmhandle_detach(&httpd->readhandle);
@@ -1158,6 +1160,7 @@ httpd_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
REQUIRE(VALID_HTTPD(httpd)); REQUIRE(VALID_HTTPD(httpd));
REQUIRE(httpd->state == SEND); REQUIRE(httpd->state == SEND);
REQUIRE(httpd->handle == handle);
isc_buffer_free(&httpd->sendbuffer); isc_buffer_free(&httpd->sendbuffer);
@@ -1176,20 +1179,33 @@ httpd_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
isc_nmhandle_detach(&httpd->sendhandle); isc_nmhandle_detach(&httpd->sendhandle);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
return; goto cleanup_readhandle;
}
if ((httpd->flags & HTTPD_CLOSE) != 0) {
goto cleanup_readhandle;
} }
httpd->state = RECV; httpd->state = RECV;
httpd->sendhandle = NULL;
if (httpd->recvlen != 0) { if (httpd->recvlen != 0) {
/* /*
* Outstanding requests still exist, start processing * Outstanding requests still exist, start processing
* them. * them.
*/ */
isc_nmhandle_attach(handle, &httpd->readhandle); httpd_request(httpd->handle, ISC_R_SUCCESS, NULL, httpd->mgr);
httpd_request(handle, ISC_R_SUCCESS, NULL, httpd->mgr);
} else if (!httpd->truncated) { } else if (!httpd->truncated) {
isc_nm_resumeread(handle); isc_nm_resumeread(httpd->readhandle);
} else {
/* Truncated request, don't resume */
goto cleanup_readhandle;
} }
return;
cleanup_readhandle:
isc_nmhandle_detach(&httpd->readhandle);
} }
isc_result_t isc_result_t

View File

@@ -377,15 +377,15 @@ struct isc__nm_uvreq {
int magic; int magic;
isc_nmsocket_t *sock; isc_nmsocket_t *sock;
isc_nmhandle_t *handle; isc_nmhandle_t *handle;
char tcplen[2]; /* The TCP DNS message length */ char tcplen[2]; /* The TCP DNS message length */
uv_buf_t uvbuf; /* translated isc_region_t, to be uv_buf_t uvbuf; /* translated isc_region_t, to be
* sent or received */ * sent or received */
isc_sockaddr_t local; /* local address */ isc_sockaddr_t local; /* local address */
isc_sockaddr_t peer; /* peer address */ isc_sockaddr_t peer; /* peer address */
isc__nm_cb_t cb; /* callback */ isc__nm_cb_t cb; /* callback */
void *cbarg; /* callback argument */ void *cbarg; /* callback argument */
uv_pipe_t ipc; /* used for sending socket isc_nm_timer_t *timer; /* TCP write timer */
* uv_handles to other threads */
union { union {
uv_handle_t handle; uv_handle_t handle;
uv_req_t req; uv_req_t req;
@@ -972,9 +972,7 @@ struct isc_nmsocket {
/*% /*%
* TCP write timeout timer. * TCP write timeout timer.
*/ */
uv_timer_t write_timer;
uint64_t write_timeout; uint64_t write_timeout;
int64_t writes;
/*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */ /*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */
isc_nmsocket_t *outer; isc_nmsocket_t *outer;
@@ -2097,7 +2095,7 @@ isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
void void
isc__nmsocket_readtimeout_cb(uv_timer_t *timer); isc__nmsocket_readtimeout_cb(uv_timer_t *timer);
void void
isc__nmsocket_writetimeout_cb(uv_timer_t *timer); isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult);
#define UV_RUNTIME_CHECK(func, ret) \ #define UV_RUNTIME_CHECK(func, ret) \
if (ret != 0) { \ if (ret != 0) { \

View File

@@ -1985,11 +1985,15 @@ isc__nm_accept_connection_log(isc_result_t result, bool can_log_quota) {
} }
void void
isc__nmsocket_writetimeout_cb(uv_timer_t *timer) { isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult) {
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)timer); isc__nm_uvreq_t *req = data;
isc_nmsocket_t *sock = NULL;
int r = uv_timer_stop(&sock->write_timer); REQUIRE(eresult == ISC_R_TIMEDOUT);
UV_RUNTIME_CHECK(uv_timer_stop, r); REQUIRE(VALID_UVREQ(req));
REQUIRE(VALID_NMSOCK(req->sock));
sock = req->sock;
isc__nmsocket_reset(sock); isc__nmsocket_reset(sock);
} }
@@ -2802,6 +2806,14 @@ isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0) {
nmhandle_detach_cb(&ievent->handle FLARG_PASS); nmhandle_detach_cb(&ievent->handle FLARG_PASS);
} }
static void
reset_shutdown(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle);
isc__nmsocket_shutdown(sock);
isc__nmsocket_detach(&sock);
}
void void
isc__nmsocket_reset(isc_nmsocket_t *sock) { isc__nmsocket_reset(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
@@ -2822,15 +2834,20 @@ isc__nmsocket_reset(isc_nmsocket_t *sock) {
break; break;
} }
if (!uv_is_closing(&sock->uv_handle.handle)) { if (!uv_is_closing(&sock->uv_handle.handle) &&
uv_is_active(&sock->uv_handle.handle))
{
/* /*
* The real shutdown will be handled in the respective * The real shutdown will be handled in the respective
* close functions. * close functions.
*/ */
int r = uv_tcp_close_reset(&sock->uv_handle.tcp, NULL); isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
int r = uv_tcp_close_reset(&sock->uv_handle.tcp,
reset_shutdown);
UV_RUNTIME_CHECK(uv_tcp_close_reset, r); UV_RUNTIME_CHECK(uv_tcp_close_reset, r);
} else {
isc__nmsocket_shutdown(sock);
} }
isc__nmsocket_shutdown(sock);
} }
void void
@@ -2871,13 +2888,27 @@ shutdown_walk_cb(uv_handle_t *handle, void *arg) {
switch (handle->type) { switch (handle->type) {
case UV_UDP: case UV_UDP:
isc__nmsocket_shutdown(sock);
return;
case UV_TCP: case UV_TCP:
break; switch (sock->type) {
case isc_nm_tcpsocket:
case isc_nm_tcpdnssocket:
case isc_nm_tlsdnssocket:
if (sock->parent == NULL) {
/* Reset the TCP connections on shutdown */
isc__nmsocket_reset(sock);
return;
}
/* FALLTHROUGH */
default:
isc__nmsocket_shutdown(sock);
}
return;
default: default:
return; return;
} }
isc__nmsocket_shutdown(sock);
} }
void void

View File

@@ -78,9 +78,6 @@ quota_accept_cb(isc_quota_t *quota, void *sock0);
static void static void
failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult); failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult);
static void
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
isc_result_t eresult);
static void static void
stop_tcp_parent(isc_nmsocket_t *sock); stop_tcp_parent(isc_nmsocket_t *sock);
static void static void
@@ -144,10 +141,6 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd); r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
if (r != 0) { if (r != 0) {
isc__nm_closesocket(sock->fd); isc__nm_closesocket(sock->fd);
@@ -542,10 +535,6 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock); LOCK(&sock->parent->lock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd); r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
@@ -718,19 +707,6 @@ destroy:
} }
} }
static void
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
isc_result_t eresult) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(VALID_UVREQ(req));
if (req->cb.send != NULL) {
isc__nm_sendcb(sock, req, eresult, true);
} else {
isc__nm_uvreq_put(&req, sock);
}
}
void void
isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
REQUIRE(VALID_NMHANDLE(handle)); REQUIRE(VALID_NMHANDLE(handle));
@@ -992,10 +968,6 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock); uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock);
r = uv_timer_init(&worker->loop, &csock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->write_timer, csock);
r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream); r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream);
if (r != 0) { if (r != 0) {
result = isc__nm_uverr2result(r); result = isc__nm_uverr2result(r);
@@ -1106,20 +1078,20 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
static void static void
tcp_send_cb(uv_write_t *req, int status) { tcp_send_cb(uv_write_t *req, int status) {
isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data; isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data;
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_UVREQ(uvreq)); REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle)); REQUIRE(VALID_NMSOCK(uvreq->sock));
isc_nmsocket_t *sock = uvreq->sock; sock = uvreq->sock;
if (--sock->writes == 0) { isc_nm_timer_stop(uvreq->timer);
int r = uv_timer_stop(&sock->write_timer); isc_nm_timer_detach(&uvreq->timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
if (status < 0) { if (status < 0) {
isc__nm_incstats(sock, STATID_SENDFAIL); isc__nm_incstats(sock, STATID_SENDFAIL);
failed_send_cb(sock, uvreq, isc__nm_uverr2result(status)); isc__nm_failed_send_cb(sock, uvreq,
isc__nm_uverr2result(status));
return; return;
} }
@@ -1143,7 +1115,7 @@ isc__nm_async_tcpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
result = tcp_send_direct(sock, uvreq); result = tcp_send_direct(sock, uvreq);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
isc__nm_incstats(sock, STATID_SENDFAIL); isc__nm_incstats(sock, STATID_SENDFAIL);
failed_send_cb(sock, uvreq, result); isc__nm_failed_send_cb(sock, uvreq, result);
} }
} }
@@ -1160,17 +1132,18 @@ tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
return (ISC_R_CANCELED); return (ISC_R_CANCELED);
} }
r = uv_timer_start(&sock->write_timer, isc__nmsocket_writetimeout_cb,
sock->write_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r);
RUNTIME_CHECK(sock->writes++ >= 0);
r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, &req->uvbuf, r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, &req->uvbuf,
1, tcp_send_cb); 1, tcp_send_cb);
if (r < 0) { if (r < 0) {
return (isc__nm_uverr2result(r)); return (isc__nm_uverr2result(r));
} }
isc_nm_timer_create(req->handle, isc__nmsocket_writetimeout_cb, req,
&req->timer);
if (sock->write_timeout > 0) {
isc_nm_timer_start(req->timer, sock->write_timeout);
}
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
@@ -1241,17 +1214,6 @@ read_timer_close_cb(uv_handle_t *handle) {
} }
} }
static void
write_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));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void static void
stop_tcp_child(isc_nmsocket_t *sock) { stop_tcp_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_tcpsocket); REQUIRE(sock->type == isc_nm_tcpsocket);
@@ -1304,8 +1266,6 @@ stop_tcp_parent(isc_nmsocket_t *sock) {
static void static void
tcp_close_direct(isc_nmsocket_t *sock) { tcp_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing)); REQUIRE(atomic_load(&sock->closing));
@@ -1327,10 +1287,8 @@ tcp_close_direct(isc_nmsocket_t *sock) {
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock); isc__nm_stop_reading(sock);
r = uv_timer_stop(&sock->write_timer); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
UV_RUNTIME_CHECK(uv_timer_stop, r); uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
} }
void void

View File

@@ -102,10 +102,6 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) { if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN; result = ISC_R_SHUTTINGDOWN;
goto error; goto error;
@@ -505,10 +501,6 @@ isc__nm_async_tcpdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock); LOCK(&sock->parent->lock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd); r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
@@ -978,10 +970,6 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock); uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock);
r = uv_timer_init(&worker->loop, &csock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->write_timer, csock);
r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream); r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream);
if (r != 0) { if (r != 0) {
result = isc__nm_uverr2result(r); result = isc__nm_uverr2result(r);
@@ -1118,14 +1106,12 @@ tcpdns_send_cb(uv_write_t *req, int status) {
isc_nmsocket_t *sock = NULL; isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_UVREQ(uvreq)); REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle)); REQUIRE(VALID_NMSOCK(uvreq->sock));
sock = uvreq->sock; sock = uvreq->sock;
if (--sock->writes == 0) { isc_nm_timer_stop(uvreq->timer);
int r = uv_timer_stop(&sock->write_timer); isc_nm_timer_detach(&uvreq->timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
if (status < 0) { if (status < 0) {
isc__nm_incstats(sock, STATID_SENDFAIL); isc__nm_incstats(sock, STATID_SENDFAIL);
@@ -1193,11 +1179,6 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
goto fail; goto fail;
} }
r = uv_timer_start(&sock->write_timer, isc__nmsocket_writetimeout_cb,
sock->write_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r);
RUNTIME_CHECK(sock->writes++ >= 0);
r = uv_write(&uvreq->uv_req.write, &sock->uv_handle.stream, bufs, nbufs, r = uv_write(&uvreq->uv_req.write, &sock->uv_handle.stream, bufs, nbufs,
tcpdns_send_cb); tcpdns_send_cb);
if (r < 0) { if (r < 0) {
@@ -1205,6 +1186,12 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
goto fail; goto fail;
} }
isc_nm_timer_create(uvreq->handle, isc__nmsocket_writetimeout_cb, uvreq,
&uvreq->timer);
if (sock->write_timeout > 0) {
isc_nm_timer_start(uvreq->timer, sock->write_timeout);
}
return; return;
fail: fail:
isc__nm_incstats(sock, STATID_SENDFAIL); isc__nm_incstats(sock, STATID_SENDFAIL);
@@ -1282,17 +1269,6 @@ read_timer_close_cb(uv_handle_t *timer) {
} }
} }
static void
write_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));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void static void
stop_tcpdns_child(isc_nmsocket_t *sock) { stop_tcpdns_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_tcpdnssocket); REQUIRE(sock->type == isc_nm_tcpdnssocket);
@@ -1345,7 +1321,6 @@ stop_tcpdns_parent(isc_nmsocket_t *sock) {
static void static void
tcpdns_close_direct(isc_nmsocket_t *sock) { tcpdns_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing)); REQUIRE(atomic_load(&sock->closing));
@@ -1361,10 +1336,8 @@ tcpdns_close_direct(isc_nmsocket_t *sock) {
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock); isc__nm_stop_reading(sock);
r = uv_timer_stop(&sock->write_timer); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
UV_RUNTIME_CHECK(uv_timer_stop, r); uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
} }
void void

View File

@@ -41,6 +41,7 @@ isc_nm_timer_create(isc_nmhandle_t *handle, isc_nm_timer_cb cb, void *cbarg,
sock = handle->sock; sock = handle->sock;
worker = &sock->mgr->workers[isc_nm_tid()]; worker = &sock->mgr->workers[isc_nm_tid()];
/* TODO: per-loop object cache */
timer = isc_mem_get(sock->mgr->mctx, sizeof(*timer)); timer = isc_mem_get(sock->mgr->mctx, sizeof(*timer));
*timer = (isc_nm_timer_t){ .cb = cb, .cbarg = cbarg }; *timer = (isc_nm_timer_t){ .cb = cb, .cbarg = cbarg };
isc_refcount_init(&timer->references, 1); isc_refcount_init(&timer->references, 1);
@@ -91,7 +92,8 @@ isc_nm_timer_detach(isc_nm_timer_t **timerp) {
REQUIRE(VALID_NMSOCK(handle->sock)); REQUIRE(VALID_NMSOCK(handle->sock));
if (isc_refcount_decrement(&timer->references) == 1) { if (isc_refcount_decrement(&timer->references) == 1) {
uv_timer_stop(&timer->timer); int r = uv_timer_stop(&timer->timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
uv_close((uv_handle_t *)&timer->timer, timer_destroy); uv_close((uv_handle_t *)&timer->timer, timer_destroy);
} }
} }

View File

@@ -118,10 +118,6 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) { if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN; result = ISC_R_SHUTTINGDOWN;
goto error; goto error;
@@ -576,10 +572,6 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock); LOCK(&sock->parent->lock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd); r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
@@ -1171,10 +1163,8 @@ tls_write_cb(uv_write_t *req, int status) {
isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data; isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data;
isc_nmsocket_t *sock = uvreq->sock; isc_nmsocket_t *sock = uvreq->sock;
if (--sock->writes == 0) { isc_nm_timer_stop(uvreq->timer);
int r = uv_timer_stop(&sock->write_timer); isc_nm_timer_detach(&uvreq->timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
free_senddata(sock); free_senddata(sock);
@@ -1215,7 +1205,8 @@ tls_cycle_output(isc_nmsocket_t *sock) {
sock->tls.senddata.base = isc_mem_get(sock->mgr->mctx, pending); sock->tls.senddata.base = isc_mem_get(sock->mgr->mctx, pending);
sock->tls.senddata.length = pending; sock->tls.senddata.length = pending;
req = isc__nm_uvreq_get(sock->mgr, sock); /* It's a bit misnomer here, but it does the right thing */
req = isc__nm_get_read_req(sock, NULL);
req->uvbuf.base = (char *)sock->tls.senddata.base; req->uvbuf.base = (char *)sock->tls.senddata.base;
req->uvbuf.len = sock->tls.senddata.length; req->uvbuf.len = sock->tls.senddata.length;
@@ -1249,12 +1240,6 @@ tls_cycle_output(isc_nmsocket_t *sock) {
break; break;
} }
r = uv_timer_start(&sock->write_timer,
isc__nmsocket_writetimeout_cb,
sock->write_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r);
RUNTIME_CHECK(sock->writes++ >= 0);
r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, r = uv_write(&req->uv_req.write, &sock->uv_handle.stream,
&req->uvbuf, 1, tls_write_cb); &req->uvbuf, 1, tls_write_cb);
if (r < 0) { if (r < 0) {
@@ -1264,6 +1249,12 @@ tls_cycle_output(isc_nmsocket_t *sock) {
break; break;
} }
isc_nm_timer_create(req->handle, isc__nmsocket_writetimeout_cb,
req, &req->timer);
if (sock->write_timeout > 0) {
isc_nm_timer_start(req->timer, sock->write_timeout);
}
break; break;
} }
@@ -1499,10 +1490,6 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock); uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock);
r = uv_timer_init(&worker->loop, &csock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->write_timer, csock);
r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream); r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream);
if (r != 0) { if (r != 0) {
result = isc__nm_uverr2result(r); result = isc__nm_uverr2result(r);
@@ -1849,17 +1836,6 @@ read_timer_close_cb(uv_handle_t *handle) {
} }
} }
static void
write_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));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void static void
stop_tlsdns_child(isc_nmsocket_t *sock) { stop_tlsdns_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_tlsdnssocket); REQUIRE(sock->type == isc_nm_tlsdnssocket);
@@ -1913,8 +1889,6 @@ stop_tlsdns_parent(isc_nmsocket_t *sock) {
static void static void
tlsdns_close_direct(isc_nmsocket_t *sock) { tlsdns_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing)); REQUIRE(atomic_load(&sock->closing));
@@ -1932,10 +1906,8 @@ tlsdns_close_direct(isc_nmsocket_t *sock) {
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock); isc__nm_stop_reading(sock);
r = uv_timer_stop(&sock->write_timer); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
UV_RUNTIME_CHECK(uv_timer_stop, r); uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
} }
void void

View File

@@ -76,9 +76,6 @@ udp_close_cb(uv_handle_t *handle);
static void static void
read_timer_close_cb(uv_handle_t *handle); read_timer_close_cb(uv_handle_t *handle);
static void
write_timer_close_cb(uv_handle_t *handle);
static void static void
udp_close_direct(isc_nmsocket_t *sock); udp_close_direct(isc_nmsocket_t *sock);
@@ -272,10 +269,6 @@ route_connect_direct(isc_nmsocket_t *sock) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) { if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN; result = ISC_R_SHUTTINGDOWN;
goto error; goto error;
@@ -454,10 +447,6 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock); LOCK(&sock->parent->lock);
r = uv_udp_open(&sock->uv_handle.udp, sock->fd); r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
@@ -874,10 +863,6 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) { if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN; result = ISC_R_SHUTTINGDOWN;
goto error; goto error;
@@ -1240,17 +1225,6 @@ read_timer_close_cb(uv_handle_t *handle) {
} }
} }
static void
write_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));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void static void
stop_udp_child(isc_nmsocket_t *sock) { stop_udp_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_udpsocket); REQUIRE(sock->type == isc_nm_udpsocket);
@@ -1303,14 +1277,11 @@ stop_udp_parent(isc_nmsocket_t *sock) {
static void static void
udp_close_direct(isc_nmsocket_t *sock) { udp_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
r = uv_timer_stop(&sock->write_timer); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
UV_RUNTIME_CHECK(uv_timer_stop, r); uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
} }
void void