2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

Merge branch '3132-add-send-timeout' into 'main'

Add timeout when writing TCP data

Closes #3132

See merge request isc-projects/bind9!5848
This commit is contained in:
Ondřej Surý
2022-02-17 08:45:17 +00:00
14 changed files with 345 additions and 69 deletions

View File

@@ -1,3 +1,7 @@
5807. [bug] Add a TCP "write" timer, and time out writing
connections after the "tcp-idle-timeout" period
has elapsed. [GL #3132]
5806. [bug] An error in checking the "blackhole" ACL could cause 5806. [bug] An error in checking the "blackhole" ACL could cause
DNS requests sent by named to fail if the DNS requests sent by named to fail if the
destination address or prefix was specifically destination address or prefix was specifically

View File

@@ -20,6 +20,11 @@ copy_setports ns1/named.conf.in ns1/named.conf
# tcp-initial-timeout interval # tcp-initial-timeout interval
# #
$PYTHON -c " $PYTHON -c "
print('large IN TXT', end=' ')
for a in range(128):
print('\"%s\"' % ('A' * 240), end=' ')
print('')
for a in range(150000): for a in range(150000):
print('%s IN NS a' % (a)) print('%s IN NS a' % (a))
print('%s IN NS b' % (a))" > ns1/large.db print('%s IN NS b' % (a))" > ns1/large.db

View File

@@ -51,7 +51,7 @@ def test_initial_timeout(port):
try: try:
(sbytes, stime) = dns.query.send_tcp(sock, msg, timeout()) (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
(response, rtime) = dns.query.receive_tcp(sock, timeout()) (response, rtime) = dns.query.receive_tcp(sock, timeout())
except ConnectionResetError as e: except ConnectionError as e:
raise EOFError from e raise EOFError from e
@@ -83,7 +83,7 @@ def test_idle_timeout(port):
try: try:
(sbytes, stime) = dns.query.send_tcp(sock, msg, timeout()) (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
(response, rtime) = dns.query.receive_tcp(sock, timeout()) (response, rtime) = dns.query.receive_tcp(sock, timeout())
except ConnectionResetError as e: except ConnectionError as e:
raise EOFError from e raise EOFError from e
@@ -152,7 +152,7 @@ def test_pipelining_timeout(port):
try: try:
(sbytes, stime) = dns.query.send_tcp(sock, msg, timeout()) (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
(response, rtime) = dns.query.receive_tcp(sock, timeout()) (response, rtime) = dns.query.receive_tcp(sock, timeout())
except ConnectionResetError as e: except ConnectionError as e:
raise EOFError from e raise EOFError from e
@@ -190,3 +190,33 @@ def test_long_axfr(port):
if soa is not None: if soa is not None:
break break
assert soa is not None assert soa is not None
@pytest.mark.dnspython
@pytest.mark.dnspython2
def test_send_timeout(port):
import dns.query
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect(("10.53.0.1", port))
# Send and receive single large RDATA over TCP
msg = create_msg("large.example.", "TXT")
(sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
(response, rtime) = dns.query.receive_tcp(sock, timeout())
# Send and receive 28 large (~32k) DNS queries that should
# fill the default maximum 208k TCP send buffer
for n in range(28):
(sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
# configure idle interval is 5 seconds, sleep 6 to make sure we are
# above the interval
time.sleep(6)
with pytest.raises(EOFError):
try:
(sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
(response, rtime) = dns.query.receive_tcp(sock, timeout())
except ConnectionError as e:
raise EOFError from e

View File

@@ -70,3 +70,9 @@ Bug Fixes
to ``none``. ``blackhole`` worked correctly when it was left unset, or to ``none``. ``blackhole`` worked correctly when it was left unset, or
if only positive-match elements were included. This has now been fixed. if only positive-match elements were included. This has now been fixed.
:gl:`#3157` :gl:`#3157`
- TCP connections could hang indefinitely if the TCP write buffers
were full because of the other party not reading sent data. This has
been fixed by adding a "write" timer. Connections that are hung
while writing will now time out after the ``tcp-idle-timeout`` period
has elapsed. :gl:`#3132`

View File

@@ -697,3 +697,6 @@ isc__nm_force_tid(int tid);
* Force the thread ID to 'tid'. This is STRICTLY for use in unit * Force the thread ID to 'tid'. This is STRICTLY for use in unit
* tests and should not be used in any production code. * tests and should not be used in any production code.
*/ */
void
isc_nmhandle_setwritetimeout(isc_nmhandle_t *handle, uint64_t write_timeout);

View File

@@ -950,10 +950,17 @@ struct isc_nmsocket {
/*% /*%
* TCP read/connect timeout timers. * TCP read/connect timeout timers.
*/ */
uv_timer_t timer; uv_timer_t read_timer;
uint64_t read_timeout; uint64_t read_timeout;
uint64_t connect_timeout; uint64_t connect_timeout;
/*%
* TCP write timeout timer.
*/
uv_timer_t write_timer;
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;
@@ -2071,12 +2078,25 @@ isc__nm_failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
void void
isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result, bool async); isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result, bool async);
void
isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
void void
isc__nm_accept_connection_log(isc_result_t result, bool can_log_quota); isc__nm_accept_connection_log(isc_result_t result, bool can_log_quota);
/*
* Timeout callbacks
*/
void
isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
void
isc__nmsocket_readtimeout_cb(uv_timer_t *timer);
void
isc__nmsocket_writetimeout_cb(uv_timer_t *timer);
/*%<
*
* Maximum number of simultaneous handles in flight supported for a single
* connected TCPDNS socket. This value was chosen arbitrarily, and may be
* changed in the future.
*/
#define STREAM_CLIENTS_PER_CONN 23 #define STREAM_CLIENTS_PER_CONN 23
#define UV_RUNTIME_CHECK(func, ret) \ #define UV_RUNTIME_CHECK(func, ret) \

View File

@@ -604,6 +604,14 @@ isc_nm_maxudp(isc_nm_t *mgr, uint32_t maxudp) {
atomic_store(&mgr->maxudp, maxudp); atomic_store(&mgr->maxudp, maxudp);
} }
void
isc_nmhandle_setwritetimeout(isc_nmhandle_t *handle, uint64_t write_timeout) {
REQUIRE(VALID_NMHANDLE(handle));
REQUIRE(VALID_NMSOCK(handle->sock));
handle->sock->write_timeout = write_timeout;
}
void void
isc_nm_settimeouts(isc_nm_t *mgr, uint32_t init, uint32_t idle, isc_nm_settimeouts(isc_nm_t *mgr, uint32_t init, uint32_t idle,
uint32_t keepalive, uint32_t advertised) { uint32_t keepalive, uint32_t advertised) {
@@ -1977,7 +1985,7 @@ isc__nm_failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
REQUIRE(req->cb.connect != NULL); REQUIRE(req->cb.connect != NULL);
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
INSIST(atomic_compare_exchange_strong(&sock->connecting, INSIST(atomic_compare_exchange_strong(&sock->connecting,
&(bool){ true }, false)); &(bool){ true }, false));
@@ -2070,7 +2078,21 @@ isc__nm_accept_connection_log(isc_result_t result, bool can_log_quota) {
isc_result_totext(result)); isc_result_totext(result));
} }
static void void
isc__nmsocket_writetimeout_cb(uv_timer_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)timer);
int r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
/* The shutdown will be handled in the respective close functions */
r = uv_tcp_close_reset(&sock->uv_handle.tcp, NULL);
UV_RUNTIME_CHECK(uv_tcp_close_reset, r);
isc__nmsocket_shutdown(sock);
}
void
isc__nmsocket_readtimeout_cb(uv_timer_t *timer) { isc__nmsocket_readtimeout_cb(uv_timer_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)timer); isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)timer);
@@ -2108,7 +2130,7 @@ isc__nmsocket_timer_restart(isc_nmsocket_t *sock) {
return; return;
} }
r = uv_timer_start(&sock->timer, r = uv_timer_start(&sock->read_timer,
isc__nmsocket_connecttimeout_cb, isc__nmsocket_connecttimeout_cb,
sock->connect_timeout + 10, 0); sock->connect_timeout + 10, 0);
UV_RUNTIME_CHECK(uv_timer_start, r); UV_RUNTIME_CHECK(uv_timer_start, r);
@@ -2120,7 +2142,8 @@ isc__nmsocket_timer_restart(isc_nmsocket_t *sock) {
return; return;
} }
r = uv_timer_start(&sock->timer, isc__nmsocket_readtimeout_cb, r = uv_timer_start(&sock->read_timer,
isc__nmsocket_readtimeout_cb,
sock->read_timeout, 0); sock->read_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r); UV_RUNTIME_CHECK(uv_timer_start, r);
} }
@@ -2130,7 +2153,7 @@ bool
isc__nmsocket_timer_running(isc_nmsocket_t *sock) { isc__nmsocket_timer_running(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
return (uv_is_active((uv_handle_t *)&sock->timer)); return (uv_is_active((uv_handle_t *)&sock->read_timer));
} }
void void
@@ -2152,7 +2175,7 @@ isc__nmsocket_timer_stop(isc_nmsocket_t *sock) {
/* uv_timer_stop() is idempotent, no need to check if running */ /* uv_timer_stop() is idempotent, no need to check if running */
r = uv_timer_stop(&sock->timer); r = uv_timer_stop(&sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r); UV_RUNTIME_CHECK(uv_timer_stop, r);
} }
@@ -2404,7 +2427,7 @@ isc_nmhandle_cleartimeout(isc_nmhandle_t *handle) {
default: default:
handle->sock->read_timeout = 0; handle->sock->read_timeout = 0;
if (uv_is_active((uv_handle_t *)&handle->sock->timer)) { if (uv_is_active((uv_handle_t *)&handle->sock->read_timer)) {
isc__nmsocket_timer_stop(handle->sock); isc__nmsocket_timer_stop(handle->sock);
} }
} }
@@ -2446,6 +2469,8 @@ isc_nmhandle_keepalive(isc_nmhandle_t *handle, bool value) {
atomic_store(&sock->keepalive, value); atomic_store(&sock->keepalive, value);
sock->read_timeout = value ? atomic_load(&sock->mgr->keepalive) sock->read_timeout = value ? atomic_load(&sock->mgr->keepalive)
: atomic_load(&sock->mgr->idle); : atomic_load(&sock->mgr->idle);
sock->write_timeout = value ? atomic_load(&sock->mgr->keepalive)
: atomic_load(&sock->mgr->idle);
break; break;
#if HAVE_LIBNGHTTP2 #if HAVE_LIBNGHTTP2
case isc_nm_tlssocket: case isc_nm_tlssocket:

View File

@@ -140,8 +140,13 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_tcp_init, r); UV_RUNTIME_CHECK(uv_tcp_init, r);
uv_handle_set_data(&sock->uv_handle.handle, sock); uv_handle_set_data(&sock->uv_handle.handle, sock);
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
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);
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) {
@@ -170,7 +175,8 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
} }
isc__nm_incstats(sock, STATID_CONNECT); isc__nm_incstats(sock, STATID_CONNECT);
uv_handle_set_data((uv_handle_t *)&sock->timer, &req->uv_req.connect); uv_handle_set_data((uv_handle_t *)&sock->read_timer,
&req->uv_req.connect);
isc__nmsocket_timer_start(sock); isc__nmsocket_timer_start(sock);
atomic_store(&sock->connected, true); atomic_store(&sock->connected, true);
@@ -231,7 +237,7 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
if (!atomic_load(&sock->connecting)) { if (!atomic_load(&sock->connecting)) {
return; return;
@@ -527,10 +533,13 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
/* This keeps the socket alive after everything else is gone */ /* This keeps the socket alive after everything else is gone */
isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL }); isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
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->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);
@@ -974,9 +983,13 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_tcp_init, r); UV_RUNTIME_CHECK(uv_tcp_init, r);
uv_handle_set_data(&csock->uv_handle.handle, csock); uv_handle_set_data(&csock->uv_handle.handle, csock);
r = uv_timer_init(&worker->loop, &csock->timer); r = uv_timer_init(&worker->loop, &csock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->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) {
@@ -1071,6 +1084,13 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
uvreq->cb.send = cb; uvreq->cb.send = cb;
uvreq->cbarg = cbarg; uvreq->cbarg = cbarg;
if (sock->write_timeout == 0) {
sock->write_timeout =
(atomic_load(&sock->keepalive)
? atomic_load(&sock->mgr->keepalive)
: atomic_load(&sock->mgr->idle));
}
ievent = isc__nm_get_netievent_tcpsend(sock->mgr, sock, uvreq); ievent = isc__nm_get_netievent_tcpsend(sock->mgr, sock, uvreq);
isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid], isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent); (isc__netievent_t *)ievent);
@@ -1081,11 +1101,17 @@ 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;
REQUIRE(VALID_UVREQ(uvreq)); REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle)); REQUIRE(VALID_NMHANDLE(uvreq->handle));
isc_nmsocket_t *sock = uvreq->sock; isc_nmsocket_t *sock = uvreq->sock;
if (--sock->writes == 0) {
int r = uv_timer_stop(&sock->write_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)); failed_send_cb(sock, uvreq, isc__nm_uverr2result(status));
@@ -1129,6 +1155,11 @@ 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) {
@@ -1192,7 +1223,7 @@ tcp_close_cb(uv_handle_t *handle) {
} }
static void static void
timer_close_cb(uv_handle_t *handle) { read_timer_close_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle); isc_nmsocket_t *sock = uv_handle_get_data(handle);
uv_handle_set_data(handle, NULL); uv_handle_set_data(handle, NULL);
@@ -1205,6 +1236,17 @@ 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);
@@ -1257,6 +1299,8 @@ 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));
@@ -1278,8 +1322,10 @@ 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);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); r = uv_timer_stop(&sock->write_timer);
uv_close((uv_handle_t *)&sock->timer, timer_close_cb); UV_RUNTIME_CHECK(uv_timer_stop, r);
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
@@ -1401,7 +1447,7 @@ isc__nm_async_tcpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker); UNUSED(worker);
uv_timer_stop(&sock->timer); uv_timer_stop(&sock->read_timer);
isc__nm_tcp_failed_read_cb(sock, ISC_R_EOF); isc__nm_tcp_failed_read_cb(sock, ISC_R_EOF);
} }

View File

@@ -37,13 +37,6 @@
#include "netmgr-int.h" #include "netmgr-int.h"
#include "uv-compat.h" #include "uv-compat.h"
/*%<
*
* Maximum number of simultaneous handles in flight supported for a single
* connected TCPDNS socket. This value was chosen arbitrarily, and may be
* changed in the future.
*/
static atomic_uint_fast32_t last_tcpdnsquota_log = ATOMIC_VAR_INIT(0); static atomic_uint_fast32_t last_tcpdnsquota_log = ATOMIC_VAR_INIT(0);
static bool static bool
@@ -105,8 +98,13 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_tcp_init, r); UV_RUNTIME_CHECK(uv_tcp_init, r);
uv_handle_set_data(&sock->uv_handle.handle, sock); uv_handle_set_data(&sock->uv_handle.handle, sock);
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
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);
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;
@@ -144,7 +142,8 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
} }
isc__nm_incstats(sock, STATID_CONNECT); isc__nm_incstats(sock, STATID_CONNECT);
uv_handle_set_data((uv_handle_t *)&sock->timer, &req->uv_req.connect); uv_handle_set_data((uv_handle_t *)&sock->read_timer,
&req->uv_req.connect);
isc__nmsocket_timer_start(sock); isc__nmsocket_timer_start(sock);
atomic_store(&sock->connected, true); atomic_store(&sock->connected, true);
@@ -205,7 +204,7 @@ tcpdns_connect_cb(uv_connect_t *uvreq, int status) {
REQUIRE(sock->tid == isc_nm_tid()); REQUIRE(sock->tid == isc_nm_tid());
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
if (!atomic_load(&sock->connecting)) { if (!atomic_load(&sock->connecting)) {
return; return;
@@ -497,9 +496,13 @@ isc__nm_async_tcpdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
/* This keeps the socket alive after everything else is gone */ /* This keeps the socket alive after everything else is gone */
isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL }); isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->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);
@@ -966,9 +969,13 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_tcp_init, r); UV_RUNTIME_CHECK(uv_tcp_init, r);
uv_handle_set_data(&csock->uv_handle.handle, csock); uv_handle_set_data(&csock->uv_handle.handle, csock);
r = uv_timer_init(&worker->loop, &csock->timer); r = uv_timer_init(&worker->loop, &csock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->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) {
@@ -1086,6 +1093,13 @@ isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
uvreq->cb.send = cb; uvreq->cb.send = cb;
uvreq->cbarg = cbarg; uvreq->cbarg = cbarg;
if (sock->write_timeout == 0) {
sock->write_timeout =
(atomic_load(&sock->keepalive)
? atomic_load(&sock->mgr->keepalive)
: atomic_load(&sock->mgr->idle));
}
ievent = isc__nm_get_netievent_tcpdnssend(sock->mgr, sock, uvreq); ievent = isc__nm_get_netievent_tcpdnssend(sock->mgr, sock, uvreq);
isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid], isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent); (isc__netievent_t *)ievent);
@@ -1103,6 +1117,11 @@ tcpdns_send_cb(uv_write_t *req, int status) {
sock = uvreq->sock; sock = uvreq->sock;
if (--sock->writes == 0) {
int r = uv_timer_stop(&sock->write_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);
isc__nm_failed_send_cb(sock, uvreq, isc__nm_failed_send_cb(sock, uvreq,
@@ -1169,6 +1188,11 @@ 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) {
@@ -1238,7 +1262,7 @@ tcpdns_close_cb(uv_handle_t *handle) {
} }
static void static void
timer_close_cb(uv_handle_t *timer) { read_timer_close_cb(uv_handle_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data(timer); isc_nmsocket_t *sock = uv_handle_get_data(timer);
uv_handle_set_data(timer, NULL); uv_handle_set_data(timer, NULL);
@@ -1253,6 +1277,17 @@ 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);
@@ -1305,6 +1340,7 @@ 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));
@@ -1320,8 +1356,10 @@ 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);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); r = uv_timer_stop(&sock->write_timer);
uv_close((uv_handle_t *)&sock->timer, timer_close_cb); UV_RUNTIME_CHECK(uv_timer_stop, r);
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

@@ -38,13 +38,6 @@
#include "openssl_shim.h" #include "openssl_shim.h"
#include "uv-compat.h" #include "uv-compat.h"
/*%<
*
* Maximum number of simultaneous handles in flight supported for a single
* connected TLSDNS socket. This value was chosen arbitrarily, and may be
* changed in the future.
*/
static atomic_uint_fast32_t last_tlsdnsquota_log = ATOMIC_VAR_INIT(0); static atomic_uint_fast32_t last_tlsdnsquota_log = ATOMIC_VAR_INIT(0);
static void static void
@@ -121,9 +114,13 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_tcp_init, r); UV_RUNTIME_CHECK(uv_tcp_init, r);
uv_handle_set_data(&sock->uv_handle.handle, sock); uv_handle_set_data(&sock->uv_handle.handle, sock);
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->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;
@@ -161,7 +158,8 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
} }
isc__nm_incstats(sock, STATID_CONNECT); isc__nm_incstats(sock, STATID_CONNECT);
uv_handle_set_data((uv_handle_t *)&sock->timer, &req->uv_req.connect); uv_handle_set_data((uv_handle_t *)&sock->read_timer,
&req->uv_req.connect);
isc__nmsocket_timer_start(sock); isc__nmsocket_timer_start(sock);
atomic_store(&sock->connected, true); atomic_store(&sock->connected, true);
@@ -569,9 +567,13 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
/* This keeps the socket alive after everything else is gone */ /* This keeps the socket alive after everything else is gone */
isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL }); isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->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);
@@ -1107,7 +1109,8 @@ tls_cycle_input(isc_nmsocket_t *sock) {
sock->tls.pending_req = NULL; sock->tls.pending_req = NULL;
isc__nmsocket_timer_stop(sock); isc__nmsocket_timer_stop(sock);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer,
sock);
INSIST(atomic_compare_exchange_strong( INSIST(atomic_compare_exchange_strong(
&sock->connecting, &(bool){ true }, false)); &sock->connecting, &(bool){ true }, false));
@@ -1163,6 +1166,11 @@ 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) {
int r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
free_senddata(sock); free_senddata(sock);
isc__nm_uvreq_put(&uvreq, sock); isc__nm_uvreq_put(&uvreq, sock);
@@ -1236,6 +1244,12 @@ 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) {
@@ -1476,9 +1490,13 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_tcp_init, r); UV_RUNTIME_CHECK(uv_tcp_init, r);
uv_handle_set_data(&csock->uv_handle.handle, csock); uv_handle_set_data(&csock->uv_handle.handle, csock);
r = uv_timer_init(&worker->loop, &csock->timer); r = uv_timer_init(&worker->loop, &csock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->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) {
@@ -1627,6 +1645,13 @@ isc__nm_tlsdns_send(isc_nmhandle_t *handle, isc_region_t *region,
uvreq->cb.send = cb; uvreq->cb.send = cb;
uvreq->cbarg = cbarg; uvreq->cbarg = cbarg;
if (sock->write_timeout == 0) {
sock->write_timeout =
(atomic_load(&sock->keepalive)
? atomic_load(&sock->mgr->keepalive)
: atomic_load(&sock->mgr->idle));
}
ievent = isc__nm_get_netievent_tlsdnssend(sock->mgr, sock, uvreq); ievent = isc__nm_get_netievent_tlsdnssend(sock->mgr, sock, uvreq);
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
(isc__netievent_t *)ievent); (isc__netievent_t *)ievent);
@@ -1804,7 +1829,7 @@ tlsdns_close_cb(uv_handle_t *handle) {
} }
static void static void
timer_close_cb(uv_handle_t *handle) { read_timer_close_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle); isc_nmsocket_t *sock = uv_handle_get_data(handle);
uv_handle_set_data(handle, NULL); uv_handle_set_data(handle, NULL);
@@ -1819,6 +1844,17 @@ 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);
@@ -1872,6 +1908,8 @@ 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));
@@ -1889,8 +1927,10 @@ 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);
uv_handle_set_data((uv_handle_t *)&sock->timer, sock); r = uv_timer_stop(&sock->write_timer);
uv_close((uv_handle_t *)&sock->timer, timer_close_cb); UV_RUNTIME_CHECK(uv_timer_stop, r);
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

@@ -74,7 +74,10 @@ static void
udp_close_cb(uv_handle_t *handle); udp_close_cb(uv_handle_t *handle);
static void static void
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);
@@ -265,9 +268,13 @@ route_connect_direct(isc_nmsocket_t *sock) {
UV_RUNTIME_CHECK(uv_udp_init, r); UV_RUNTIME_CHECK(uv_udp_init, r);
uv_handle_set_data(&sock->uv_handle.handle, sock); uv_handle_set_data(&sock->uv_handle.handle, sock);
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->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;
@@ -441,9 +448,13 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
/* This keeps the socket alive after everything else is gone */ /* This keeps the socket alive after everything else is gone */
isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL }); isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->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);
@@ -857,9 +868,13 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_udp_init, r); UV_RUNTIME_CHECK(uv_udp_init, r);
uv_handle_set_data(&sock->uv_handle.handle, sock); uv_handle_set_data(&sock->uv_handle.handle, sock);
r = uv_timer_init(&worker->loop, &sock->timer); r = uv_timer_init(&worker->loop, &sock->read_timer);
UV_RUNTIME_CHECK(uv_timer_init, r); UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->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;
@@ -1210,7 +1225,7 @@ udp_close_cb(uv_handle_t *handle) {
} }
static void static void
timer_close_cb(uv_handle_t *handle) { read_timer_close_cb(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle); isc_nmsocket_t *sock = uv_handle_get_data(handle);
uv_handle_set_data(handle, NULL); uv_handle_set_data(handle, NULL);
@@ -1221,6 +1236,17 @@ 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);
@@ -1273,10 +1299,14 @@ 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());
uv_close((uv_handle_t *)&sock->timer, timer_close_cb); r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
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

@@ -42,6 +42,24 @@ isc_uv_udp_connect(uv_udp_t *handle, const struct sockaddr *addr) {
} }
#endif /* UV_VERSION_HEX < UV_VERSION(1, 27, 0) */ #endif /* UV_VERSION_HEX < UV_VERSION(1, 27, 0) */
#if UV_VERSION_HEX < UV_VERSION(1, 32, 0)
int
uv_tcp_close_reset(uv_tcp_t *handle, uv_close_cb close_cb) {
if (setsockopt(handle->io_watcher.fd, SOL_SOCKET, SO_LINGER,
&(struct linger){ 1, 0 }, sizeof(struct linger)) == -1)
{
#if UV_VERSION_HEX >= UV_VERSION(1, 10, 0)
return (uv_translate_sys_error(errno));
#else
return (-errno);
#endif /* UV_VERSION_HEX >= UV_VERSION(1, 10, 0) */
}
uv_close((uv_handle_t *)handle, close_cb);
return (0);
}
#endif /* UV_VERSION_HEX < UV_VERSION(1, 32, 0) */
int int
isc_uv_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr, isc_uv_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr,
unsigned int flags) { unsigned int flags) {

View File

@@ -23,6 +23,10 @@
#define UV_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) #define UV_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
#if !defined(UV__ERR)
#define UV__ERR(x) (-(x))
#endif
#if UV_VERSION_HEX < UV_VERSION(1, 19, 0) #if UV_VERSION_HEX < UV_VERSION(1, 19, 0)
static inline void * static inline void *
uv_handle_get_data(const uv_handle_t *handle) { uv_handle_get_data(const uv_handle_t *handle) {
@@ -45,6 +49,11 @@ uv_req_set_data(uv_req_t *req, void *data) {
} }
#endif /* UV_VERSION_HEX < UV_VERSION(1, 19, 0) */ #endif /* UV_VERSION_HEX < UV_VERSION(1, 19, 0) */
#if UV_VERSION_HEX < UV_VERSION(1, 32, 0)
int
uv_tcp_close_reset(uv_tcp_t *handle, uv_close_cb close_cb);
#endif
#if UV_VERSION_HEX < UV_VERSION(1, 34, 0) #if UV_VERSION_HEX < UV_VERSION(1, 34, 0)
#define uv_sleep(msec) usleep(msec * 1000) #define uv_sleep(msec) usleep(msec * 1000)
#endif /* UV_VERSION_HEX < UV_VERSION(1, 34, 0) */ #endif /* UV_VERSION_HEX < UV_VERSION(1, 34, 0) */

View File

@@ -437,6 +437,7 @@ connect_send(isc_nmhandle_t *handle) {
isc_nmhandle_t *sendhandle = NULL; isc_nmhandle_t *sendhandle = NULL;
isc_refcount_increment0(&active_csends); isc_refcount_increment0(&active_csends);
isc_nmhandle_attach(handle, &sendhandle); isc_nmhandle_attach(handle, &sendhandle);
isc_nmhandle_setwritetimeout(handle, T_IDLE);
if (atomic_fetch_sub(&nsends, 1) > 1) { if (atomic_fetch_sub(&nsends, 1) > 1) {
isc_nm_send(sendhandle, (isc_region_t *)&send_msg, isc_nm_send(sendhandle, (isc_region_t *)&send_msg,
connect_send_cb, NULL); connect_send_cb, NULL);
@@ -548,6 +549,7 @@ listen_read_cb(isc_nmhandle_t *handle, isc_result_t eresult,
isc_nmhandle_t *sendhandle = NULL; isc_nmhandle_t *sendhandle = NULL;
isc_nmhandle_attach(handle, &sendhandle); isc_nmhandle_attach(handle, &sendhandle);
isc_refcount_increment0(&active_ssends); isc_refcount_increment0(&active_ssends);
isc_nmhandle_setwritetimeout(sendhandle, T_IDLE);
isc_nm_send(sendhandle, (isc_region_t *)&send_msg, isc_nm_send(sendhandle, (isc_region_t *)&send_msg,
listen_send_cb, cbarg); listen_send_cb, cbarg);
} }