void
isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
-void
+isc_result_t
isc__nm_start_reading(isc_nmsocket_t *sock);
void
isc__nm_stop_reading(isc_nmsocket_t *sock);
-void
+isc_result_t
isc__nm_process_sock_buffer(isc_nmsocket_t *sock);
void
isc__nm_resume_processing(void *arg);
worker->recvbuf_inuse = true;
}
-void
+isc_result_t
isc__nm_start_reading(isc_nmsocket_t *sock) {
+ isc_result_t result = ISC_R_SUCCESS;
int r;
if (atomic_load(&sock->reading)) {
- return;
+ return (ISC_R_SUCCESS);
}
switch (sock->type) {
case isc_nm_udpsocket:
r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
isc__nm_udp_read_cb);
- UV_RUNTIME_CHECK(uv_udp_recv_start, r);
break;
case isc_nm_tcpsocket:
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
isc__nm_tcp_read_cb);
- UV_RUNTIME_CHECK(uv_read_start, r);
break;
case isc_nm_tcpdnssocket:
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
isc__nm_tcpdns_read_cb);
- UV_RUNTIME_CHECK(uv_read_start, r);
break;
case isc_nm_tlsdnssocket:
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
isc__nm_tlsdns_read_cb);
- UV_RUNTIME_CHECK(uv_read_start, r);
break;
default:
UNREACHABLE();
}
- atomic_store(&sock->reading, true);
+ if (r != 0) {
+ result = isc_uverr2result(r);
+ } else {
+ atomic_store(&sock->reading, true);
+ }
+
+ return (result);
}
void
* Stop reading if this is a client socket. In this case we'll be
* called again later by isc__nm_resume_processing().
*/
-void
+isc_result_t
isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
for (;;) {
int_fast32_t ah = atomic_load(&sock->ah);
* Don't reset the timer until we have a
* full DNS message.
*/
- isc__nm_start_reading(sock);
+ result = isc__nm_start_reading(sock);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
/*
* Start the timer only if there are no externally used
* active handles, there's always one active handle
if (ah == 1) {
isc__nmsocket_timer_start(sock);
}
- return;
+ goto done;
case ISC_R_CANCELED:
isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock);
- return;
+ goto done;
case ISC_R_SUCCESS:
/*
* Stop the timer on the successful message read, this
if (atomic_load(&sock->client)) {
isc__nm_stop_reading(sock);
- return;
+ goto done;
}
break;
default:
UNREACHABLE();
}
}
+done:
+ return (ISC_R_SUCCESS);
}
void
isc__netievent_tcpstartread_t *ievent =
(isc__netievent_tcpstartread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
+ isc_result_t result;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
if (isc__nmsocket_closing(sock)) {
+ result = ISC_R_CANCELED;
+ } else {
+ result = isc__nm_start_reading(sock);
+ }
+
+ if (result != ISC_R_SUCCESS) {
atomic_store(&sock->reading, true);
- isc__nm_tcp_failed_read_cb(sock, ISC_R_CANCELED);
+ isc__nm_tcp_failed_read_cb(sock, result);
return;
}
- isc__nm_start_reading(sock);
isc__nmsocket_timer_start(sock);
}
isc__netievent_tcpdnsread_t *ievent =
(isc__netievent_tcpdnsread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
+ isc_result_t result;
UNUSED(worker);
REQUIRE(sock->tid == isc_nm_tid());
if (isc__nmsocket_closing(sock)) {
- atomic_store(&sock->reading, true);
- isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
- return;
+ result = ISC_R_CANCELED;
+ } else {
+ result = isc__nm_process_sock_buffer(sock);
}
- isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ atomic_store(&sock->reading, true);
+ isc__nm_failed_read_cb(sock, result, false);
+ }
}
/*
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream);
uint8_t *base = NULL;
size_t len;
+ isc_result_t result;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
sock->read_timeout = atomic_load(&sock->mgr->idle);
}
- isc__nm_process_sock_buffer(sock);
+ result = isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ isc__nm_failed_read_cb(sock, result, true);
+ }
free:
if (nread < 0) {
/*
* prep_destroy()->tcpdns_close_direct().
*/
isc_nmhandle_attach(handle, &csock->recv_handle);
- isc__nm_process_sock_buffer(csock);
+ result = isc__nm_process_sock_buffer(csock);
+ if (result != ISC_R_SUCCESS) {
+ isc_nmhandle_detach(&csock->recv_handle);
+ isc_nmhandle_detach(&handle);
+ goto failure;
+ }
/*
* The initial timer has been set, update the read timeout for the next
/* Setting pending req */
sock->tls.pending_req = req;
- isc__nm_process_sock_buffer(sock);
+ result = isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ sock->tls.pending_req = NULL;
+ goto error;
+ }
result = tls_cycle(sock);
if (result != ISC_R_SUCCESS) {
/*
* Process what's in the buffer so far
*/
- isc__nm_process_sock_buffer(sock);
-
+ result = isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ goto failure;
+ }
/*
* FIXME: Should we call
* isc__nm_failed_read_cb()?
sock->buf_len += len;
- isc__nm_process_sock_buffer(sock);
+ result = isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ goto failure;
+ }
}
} else if (!SSL_is_init_finished(sock->tls.tls)) {
if (SSL_is_server(sock->tls.tls)) {
if (sock->tls.state == TLS_STATE_NONE &&
!SSL_is_init_finished(sock->tls.tls)) {
sock->tls.state = TLS_STATE_HANDSHAKE;
- isc__nm_process_sock_buffer(sock);
+ result = isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ goto failure;
+ }
}
/* else continue reading */
break;
isc_nmhandle_detach(&handle);
- isc__nm_process_sock_buffer(csock);
+ result = isc__nm_process_sock_buffer(csock);
+ if (result != ISC_R_SUCCESS) {
+ goto failure;
+ }
/*
* sock is now attached to the handle.
isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent_udpread_t *ievent = (isc__netievent_udpread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
- isc_result_t result = ISC_R_SUCCESS;
+ isc_result_t result;
UNUSED(worker);
result = ISC_R_SHUTTINGDOWN;
} else if (isc__nmsocket_closing(sock)) {
result = ISC_R_CANCELED;
+ } else {
+ result = isc__nm_start_reading(sock);
}
if (result != ISC_R_SUCCESS) {
return;
}
- isc__nm_start_reading(sock);
isc__nmsocket_timer_start(sock);
}