mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Merge the common parts between udp, tcpdns and tlsdns protocol
The udp, tcpdns and tlsdns contained lot of cut&paste code or code that was very similar making the stack harder to maintain as any change to one would have to be copied to the the other protocols. In this commit, we merge the common parts into the common functions under isc__nm_<foo> namespace and just keep the little differences based on the socket type.
This commit is contained in:
@@ -50,33 +50,11 @@ timer_close_cb(uv_handle_t *handle);
|
||||
static void
|
||||
udp_close_direct(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
|
||||
|
||||
static void
|
||||
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
isc_result_t eresult);
|
||||
|
||||
static void
|
||||
stop_udp_parent(isc_nmsocket_t *sock);
|
||||
static void
|
||||
stop_udp_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, isc_sockaddr_t *sockaddr);
|
||||
|
||||
static bool
|
||||
inactive(isc_nmsocket_t *sock) {
|
||||
return (!isc__nmsocket_active(sock) ||
|
||||
atomic_load(&sock->mgr->closing) ||
|
||||
(sock->server != NULL && !isc__nmsocket_active(sock->server)));
|
||||
}
|
||||
|
||||
static uv_os_sock_t
|
||||
isc__nm_udp_lb_socket(sa_family_t sa_family) {
|
||||
isc_result_t result;
|
||||
@@ -192,32 +170,6 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*%<
|
||||
* Allocator for UDP recv operations. Limited to size 20 * (2^16 + 2),
|
||||
* which allows enough space for recvmmsg() to get multiple messages at
|
||||
* a time.
|
||||
*
|
||||
* 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
|
||||
udp_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_udpsocket);
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE);
|
||||
|
||||
worker = &sock->mgr->workers[sock->tid];
|
||||
INSIST(!worker->recvbuf_inuse);
|
||||
|
||||
buf->base = worker->recvbuf;
|
||||
buf->len = ISC_NETMGR_RECVBUF_SIZE;
|
||||
worker->recvbuf_inuse = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Asynchronous 'udplisten' call handler: start listening on a UDP socket.
|
||||
*/
|
||||
@@ -306,7 +258,8 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
uv_send_buffer_size(&sock->uv_handle.handle,
|
||||
&(int){ ISC_SEND_BUFFER_SIZE });
|
||||
#endif
|
||||
r = uv_udp_recv_start(&sock->uv_handle.udp, udp_alloc_cb, udp_recv_cb);
|
||||
r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
|
||||
udp_recv_cb);
|
||||
if (r != 0) {
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_BINDFAIL]);
|
||||
goto done;
|
||||
@@ -430,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) {
|
||||
failed_read_cb(sock, ISC_R_EOF);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF);
|
||||
goto free;
|
||||
}
|
||||
|
||||
@@ -438,19 +391,19 @@ 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)) {
|
||||
failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
goto free;
|
||||
}
|
||||
|
||||
if (nrecv < 0) {
|
||||
failed_read_cb(sock, isc__nm_uverr2result(nrecv));
|
||||
isc__nm_failed_read_cb(sock, isc__nm_uverr2result(nrecv));
|
||||
goto free;
|
||||
}
|
||||
|
||||
result = isc_sockaddr_fromsockaddr(&sockaddr, addr);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
req = get_read_req(sock, &sockaddr);
|
||||
req = isc__nm_get_read_req(sock, &sockaddr);
|
||||
|
||||
/*
|
||||
* The callback will be called synchronously, because result is
|
||||
@@ -570,15 +523,15 @@ isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
UNUSED(worker);
|
||||
|
||||
if (inactive(sock)) {
|
||||
failed_send_cb(sock, uvreq, ISC_R_CANCELED);
|
||||
if (isc__nm_inactive(sock)) {
|
||||
isc__nm_failed_send_cb(sock, uvreq, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
result = udp_send_direct(sock, uvreq, &ievent->peer);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_SENDFAIL]);
|
||||
failed_send_cb(sock, uvreq, result);
|
||||
isc__nm_failed_send_cb(sock, uvreq, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,7 +567,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 (inactive(sock)) {
|
||||
if (isc__nm_inactive(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
@@ -839,9 +792,9 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
const struct sockaddr *addr, unsigned flags) {
|
||||
void
|
||||
isc__nm_udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
const struct sockaddr *addr, unsigned flags) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle);
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
@@ -854,17 +807,17 @@ udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
||||
* does not.
|
||||
*/
|
||||
if (!sock->parent) {
|
||||
stop_reading(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
||||
void
|
||||
isc__nm_udp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(result != ISC_R_SUCCESS);
|
||||
|
||||
if (atomic_load(&sock->client)) {
|
||||
stop_reading(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
if (!sock->recv_read) {
|
||||
goto destroy;
|
||||
@@ -872,7 +825,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, NULL);
|
||||
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
||||
isc__nmsocket_clearcb(sock);
|
||||
isc__nm_readcb(sock, req, result);
|
||||
}
|
||||
@@ -895,46 +848,11 @@ 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, NULL);
|
||||
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
||||
isc__nm_readcb(sock, req, result);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_udp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
||||
failed_read_cb(sock, result);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static isc__nm_uvreq_t *
|
||||
get_read_req(isc_nmsocket_t *sock, isc_sockaddr_t *sockaddr) {
|
||||
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;
|
||||
|
||||
if (atomic_load(&sock->client)) {
|
||||
isc_nmhandle_attach(sock->statichandle, &req->handle);
|
||||
} else {
|
||||
req->handle = isc__nmhandle_get(sock, sockaddr, NULL);
|
||||
}
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
/*
|
||||
* Asynchronous 'udpread' call handler: start or resume reading on a
|
||||
* socket; pause reading and call the 'recv' callback after each
|
||||
@@ -950,41 +868,16 @@ isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
if (inactive(sock)) {
|
||||
if (isc__nm_inactive(sock)) {
|
||||
sock->reading = true;
|
||||
failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
start_reading(sock);
|
||||
isc__nm_start_reading(sock);
|
||||
isc__nmsocket_timer_start(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
start_reading(isc_nmsocket_t *sock) {
|
||||
if (sock->reading) {
|
||||
return;
|
||||
}
|
||||
|
||||
int r = uv_udp_recv_start(&sock->uv_handle.udp, udp_alloc_cb,
|
||||
udp_read_cb);
|
||||
REQUIRE(r == 0);
|
||||
sock->reading = true;
|
||||
}
|
||||
|
||||
static void
|
||||
stop_reading(isc_nmsocket_t *sock) {
|
||||
if (!sock->reading) {
|
||||
return;
|
||||
}
|
||||
|
||||
int r = uv_udp_recv_stop(&sock->uv_handle.udp);
|
||||
REQUIRE(r == 0);
|
||||
sock->reading = false;
|
||||
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_udp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
@@ -1192,7 +1085,7 @@ isc__nm_udp_shutdown(isc_nmsocket_t *sock) {
|
||||
* interested in the callback.
|
||||
*/
|
||||
if (sock->statichandle) {
|
||||
failed_read_cb(sock, ISC_R_CANCELED);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_CANCELED);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1236,5 +1129,5 @@ isc__nm_async_udpcancel(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(atomic_load(&sock->client));
|
||||
|
||||
failed_read_cb(sock, ISC_R_EOF);
|
||||
isc__nm_failed_read_cb(sock, ISC_R_EOF);
|
||||
}
|
||||
|
Reference in New Issue
Block a user