Fix xfrin_connect_done() error paths

The xfrin_connect_done() had several problems:

- it would not add the server to unreachable table in case of the
  failure coming from the dispatch [GL #3989]

- if dns_dispatch_checkperm() disallowed the connection, the xfr would
  be left undetached

- if xfrin_send_request() failed to send the request, the xfr would be
  left undetached

All of these have been fixed in this commit.

(cherry picked from commit 536e439c79)
This commit is contained in:
Ondřej Surý 2023-04-03 14:56:17 +02:00
parent 3d341d090b
commit 2bb4fa34cc
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41

View file

@ -1221,7 +1221,6 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
const char *signer = "", *sep = "";
isc_sockaddr_t sockaddr;
dns_zonemgr_t *zmgr = NULL;
isc_time_t now;
REQUIRE(VALID_XFRIN(xfr));
@ -1231,21 +1230,21 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
result = ISC_R_SHUTTINGDOWN;
}
CHECK(result);
if (result != ISC_R_SUCCESS) {
xfrin_fail(xfr, result, "failed to connect");
goto failure;
}
CHECK(isc_nm_xfr_checkperm(handle));
result = isc_nm_xfr_checkperm(handle);
if (result != ISC_R_SUCCESS) {
xfrin_fail(xfr, result, "connected but unable to transfer");
goto failure;
}
zmgr = dns_zone_getmgr(xfr->zone);
if (zmgr != NULL) {
if (result != ISC_R_SUCCESS) {
TIME_NOW(&now);
dns_zonemgr_unreachableadd(zmgr, &xfr->primaryaddr,
&xfr->sourceaddr, &now);
CHECK(result);
} else {
dns_zonemgr_unreachabledel(zmgr, &xfr->primaryaddr,
&xfr->sourceaddr);
}
dns_zonemgr_unreachabledel(zmgr, &xfr->primaryaddr,
&xfr->sourceaddr);
}
xfr->handle = handle;
@ -1262,14 +1261,40 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", sourcetext, sep,
signer);
CHECK(xfrin_send_request(xfr));
failure:
result = xfrin_send_request(xfr);
if (result != ISC_R_SUCCESS) {
xfrin_fail(xfr, result, "failed to connect");
xfrin_fail(xfr, result, "connected but unable to send");
}
dns_xfrin_detach(&xfr); /* connect_xfr */
failure:
switch (result) {
case ISC_R_SUCCESS:
break;
case ISC_R_NETDOWN:
case ISC_R_HOSTDOWN:
case ISC_R_NETUNREACH:
case ISC_R_HOSTUNREACH:
case ISC_R_CONNREFUSED:
/*
* Add the server to unreachable primaries table only if
* the server has a permanent networking error.
*/
zmgr = dns_zone_getmgr(xfr->zone);
if (zmgr != NULL) {
isc_time_t now;
TIME_NOW(&now);
dns_zonemgr_unreachableadd(zmgr, &xfr->primaryaddr,
&xfr->sourceaddr, &now);
}
break;
default:
/* Retry sooner than in 10 minutes */
break;
}
dns_xfrin_detach(&xfr);
}
/*