clean up some handle/client reference counting errors in error cases.

We weren't consistent about who should unreference the handle in
case of network error. Make it consistent so that it's always the
client code responsibility to unreference the handle - either
in the callback or right away if send function failed and the callback
will never be called.
This commit is contained in:
Witold Kręcicki
2020-01-17 11:42:35 +01:00
parent dcc0835a3a
commit 8d6dc8613a
4 changed files with 19 additions and 10 deletions

View File

@@ -470,8 +470,7 @@ isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
REQUIRE(sock->type == isc_nm_tcpdnssocket);
if (sock->outer == NULL) {
/* The socket is closed, just issue the callback */
cb(handle, ISC_R_FAILURE, cbarg);
/* The socket is closed */
return (ISC_R_NOTCONNECTED);
}

View File

@@ -366,7 +366,11 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region,
/*
* Simulate a firewall blocking UDP packets bigger than
* 'maxudp' bytes.
* 'maxudp' bytes, for testing purposes.
*
* The client would ordinarily have unreferenced the handle
* in the callback, but that won't happen in this case, so
* we need to do so here.
*/
if (maxudp != 0 && region->length > maxudp) {
isc_nmhandle_unref(handle);
@@ -379,12 +383,10 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region,
} else if (sock->type == isc_nm_udplistener) {
psock = sock;
} else {
isc_nmhandle_unref(handle);
return (ISC_R_UNEXPECTED);
}
if (!isc__nmsocket_active(sock)) {
isc_nmhandle_unref(handle);
return (ISC_R_CANCELED);
}

View File

@@ -381,8 +381,9 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
r.base[1] = client->message->id & 0xff;
result = client_sendpkg(client, &buffer);
if (result == ISC_R_SUCCESS)
if (result == ISC_R_SUCCESS) {
return;
}
done:
if (client->tcpbuf != NULL) {
@@ -392,6 +393,7 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
}
ns_client_drop(client, result);
isc_nmhandle_unref(client->handle);
}
void
@@ -596,6 +598,10 @@ ns_client_send(ns_client_t *client) {
isc_nmhandle_ref(client->handle);
result = client_sendpkg(client, &tcpbuffer);
if (result != ISC_R_SUCCESS) {
/* We won't get a callback to clean it up */
isc_nmhandle_unref(client->handle);
}
switch (isc_sockaddr_pf(&client->peeraddr)) {
case AF_INET:
@@ -629,6 +635,10 @@ ns_client_send(ns_client_t *client) {
isc_nmhandle_ref(client->handle);
result = client_sendpkg(client, &buffer);
if (result != ISC_R_SUCCESS) {
/* We won't get a callback to clean it up */
isc_nmhandle_unref(client->handle);
}
switch (isc_sockaddr_pf(&client->peeraddr)) {
case AF_INET:

View File

@@ -1663,8 +1663,6 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
xfrout_fail(xfr, result, "send");
} else if (xfr->end_of_stream == false) {
sendstream(xfr);
/* Return now so we don't unref the handle */
return;
} else {
/* End of zone transfer stream. */
uint64_t msecs, persec;
@@ -1690,9 +1688,9 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
(unsigned int) persec);
xfrout_ctx_destroy(&xfr);
/* We're done, unreference the handle */
isc_nmhandle_unref(handle);
}
isc_nmhandle_unref(handle);
}
static void