bool
isc_nmhandle_is_stream(isc_nmhandle_t *handle);
-/*
- * isc_nmhandle_t has a void * opaque field (usually - ns_client_t).
+void
+isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg,
+ isc_nm_opaquecb_t doreset, isc_nm_opaquecb_t dofree);
+/*%<
+ * isc_nmhandle_t has a void* opaque field (for example, ns_client_t).
* We reuse handle and `opaque` can also be reused between calls.
* This function sets this field and two callbacks:
* - doreset resets the `opaque` to initial state
* - dofree frees everything associated with `opaque`
*/
+
void
-isc_nmhandle_setdata(isc_nmhandle_t *handle, void *arg,
- isc_nm_opaquecb_t doreset, isc_nm_opaquecb_t dofree);
+isc_nmhandle_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the read/recv timeout for the socket connected to 'handle'
+ * to 'timeout', and reset the timer.
+ *
+ * When this is called on a 'wrapper' socket handle (for example,
+ * a TCPDNS socket wrapping a TCP connection), the timer is set for
+ * both socket layers.
+ */
isc_sockaddr_t
isc_nmhandle_peeraddr(isc_nmhandle_t *handle);
*/
void
-isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle);
+isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle, bool value);
/*%<
- * Enable keepalive on this connection.
+ * Enable/disable keepalive on this connection by setting it to 'value'.
*
* When keepalive is active, we switch to using the keepalive timeout
* to determine when to close a connection, rather than the idle timeout.
void
isc__nm_udp_stoplistening(isc_nmsocket_t *sock);
+/*%<
+ * Stop listening on 'sock'.
+ */
+
+void
+isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the recv timeout for the UDP socket associated with 'handle'.
+ */
void
isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_tcp_stoplistening(isc_nmsocket_t *sock);
+/*%<
+ * Stop listening on 'sock'.
+ */
+
+void
+isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the read timeout for the TCP socket associated with 'handle'.
+ */
void
isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0);
void
isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock);
+/*%<
+ * Stop listening on 'sock'.
+ */
+
+void
+isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
+/*%<
+ * Set the read timeout and reset the timer for the TCPDNS socket
+ * associated with 'handle', and the TCP socket it wraps around.
+ */
void
isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0);
handle->dofree = dofree;
}
+void
+isc_nmhandle_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+ REQUIRE(VALID_NMHANDLE(handle));
+
+ switch (handle->sock->type) {
+ case isc_nm_udpsocket:
+ isc__nm_udp_settimeout(handle, timeout);
+ break;
+ case isc_nm_tcpsocket:
+ isc__nm_tcp_settimeout(handle, timeout);
+ break;
+ case isc_nm_tcpdnssocket:
+ isc__nm_tcpdns_settimeout(handle, timeout);
+ break;
+ default:
+ INSIST(0);
+ ISC_UNREACHABLE();
+ }
+}
+
void *
isc_nmhandle_getextra(isc_nmhandle_t *handle) {
REQUIRE(VALID_NMHANDLE(handle));
sock->recv_cb = cb;
sock->recv_cbarg = cbarg;
+ sock->read_timeout = (atomic_load(&sock->keepalive)
+ ? sock->mgr->keepalive
+ : sock->mgr->idle);
+
ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstartread);
ievent->sock = sock;
if (sock->read_timeout != 0) {
if (!sock->timer_initialized) {
uv_timer_init(&worker->loop, &sock->timer);
- uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
sock->timer_initialized = true;
}
+ uv_handle_set_data((uv_handle_t *)&sock->timer, sock);
uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout,
0);
sock->timer_running = true;
cb(sock->statichandle, ISC_R_SUCCESS, ®ion, cbarg);
}
- sock->read_timeout = (atomic_load(&sock->keepalive)
- ? sock->mgr->keepalive
- : sock->mgr->idle);
-
if (sock->timer_initialized && sock->read_timeout != 0) {
/* The timer will be updated */
uv_timer_start(&sock->timer, readtimeout_cb,
isc_nmhandle_detach(&handle);
}
+
+void
+isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+ isc_nmsocket_t *sock = NULL;
+
+ REQUIRE(VALID_NMHANDLE(handle));
+
+ sock = handle->sock;
+
+ sock->read_timeout = timeout;
+ if (sock->timer_running) {
+ uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout,
+ 0);
+ }
+}
}
void
-isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle) {
+isc_nm_tcpdns_keepalive(isc_nmhandle_t *handle, bool value) {
REQUIRE(VALID_NMHANDLE(handle));
if (handle->sock->type != isc_nm_tcpdnssocket ||
return;
}
- atomic_store(&handle->sock->keepalive, true);
- atomic_store(&handle->sock->outerhandle->sock->keepalive, true);
+ atomic_store(&handle->sock->keepalive, value);
+ atomic_store(&handle->sock->outerhandle->sock->keepalive, value);
}
static void
sock->recv_cb = cb;
sock->recv_cbarg = cbarg;
+ sock->read_timeout = (atomic_load(&sock->keepalive)
+ ? sock->mgr->keepalive
+ : sock->mgr->idle);
+
/*
* Add a reference to the handle to keep it from being freed by
* the caller; it will be detached in in isc__nm_async_tcpdnsread().
isc_nmhandle_detach(&handle);
}
+
+void
+isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+ isc_nmsocket_t *sock = NULL;
+
+ REQUIRE(VALID_NMHANDLE(handle));
+
+ sock = handle->sock;
+
+ if (sock->outerhandle != NULL) {
+ isc__nm_tcp_settimeout(sock->outerhandle, timeout);
+ }
+
+ sock->read_timeout = timeout;
+ if (sock->timer_running) {
+ uv_timer_start(&sock->timer, dnstcp_readtimeout,
+ sock->read_timeout, 0);
+ }
+}
isc_nmhandle_detach(&handle);
}
+
+void
+isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
+ isc_nmsocket_t *sock = NULL;
+
+ REQUIRE(VALID_NMHANDLE(handle));
+
+ sock = handle->sock;
+
+ sock->read_timeout = timeout;
+ if (sock->timer_running) {
+ uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout,
+ 0);
+ }
+}
isc_nmhandle_localaddr
isc_nmhandle_peeraddr
isc_nmhandle_setdata
+isc_nmhandle_settimeout
isc_nm_cancelread
isc_nm_closedown
isc_nm_destroy