Commit 8d6dc861 authored by Witold Krecicki's avatar Witold Krecicki

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.
parent dcc0835a
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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:
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment