Commit 56183a39 authored by Witold Kręcicki's avatar Witold Kręcicki

Fix a race in fctx_cancelquery.

When sending an udp query (resquery_send) we first issue an asynchronous
isc_socket_connect and increment query->connects, then isc_socket_sendto2
and increment query->sends.
If we happen to cancel this query (fctx_cancelquery) we need to cancel
all operations we might have issued on this socket. If we are under very high
load the callback from isc_socket_connect (resquery_udpconnected) might have
not yet been fired. In this case we only cancel the CONNECT event on socket,
and ignore the SEND that's waiting there (as there is an `else if`).
Then we call dns_dispatch_removeresponse which kills the dispatcher socket
and calls isc_socket_close - but if system is under very high load, the send
we issued earlier might still not be complete - which triggers an assertion
because we're trying to close a socket that's still in use.

The fix is to always check if we have incomplete sends on the socket and cancel
them if we do.
parent 3365064f
......@@ -1321,7 +1321,8 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
isc_socket_cancel(sock, NULL,
ISC_SOCKCANCEL_CONNECT);
}
} else if (RESQUERY_SENDING(query)) {
}
if (RESQUERY_SENDING(query)) {
/*
* Cancel the pending send.
*/
......
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