move UDP connect retries from dig into isc_nm_udpconnect()

dig previously ran isc_nm_udpconnect() three times before giving
up, to work around a freebsd bug that caused connect() to return
a spurious transient EADDRINUSE. this commit moves the retry code
into the network manager itself, so that isc_nm_udpconnect() no
longer needs to return a result code.
This commit is contained in:
Evan Hunt
2021-04-01 14:02:03 -07:00
committed by Ondřej Surý
parent ca12e25bb0
commit a70cd026df
3 changed files with 25 additions and 37 deletions

View File

@@ -2794,12 +2794,11 @@ start_tcp(dig_query_t *query) {
if (query->lookup->tls_mode) {
result = isc_tlsctx_createclient(&query->tlsctx);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = isc_nm_tlsdnsconnect(
netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr,
tcp_connected, query, local_timeout, 0,
query->tlsctx);
check_result(result, "isc_nm_tlsdnsconnect");
isc_nm_tlsdnsconnect(netmgr,
(isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr,
tcp_connected, query,
local_timeout, 0, query->tlsctx);
} else if (query->lookup->https_mode) {
char uri[4096] = { 0 };
snprintf(uri, sizeof(uri), "https://%s:%u%s",
@@ -2814,18 +2813,16 @@ start_tcp(dig_query_t *query) {
query->tlsctx);
}
result = isc_nm_httpconnect(
netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr, uri,
!query->lookup->https_get, tcp_connected, query,
query->tlsctx, local_timeout, 0);
check_result(result, "isc_nm_httpconnect");
isc_nm_httpconnect(netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr,
uri, !query->lookup->https_get,
tcp_connected, query, query->tlsctx,
local_timeout, 0);
} else {
result = isc_nm_tcpdnsconnect(
isc_nm_tcpdnsconnect(
netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr,
tcp_connected, query, local_timeout, 0);
check_result(result, "isc_nm_tcpdnsconnect");
}
/* XXX: set DSCP */
@@ -2904,9 +2901,7 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
debug("udp setup failed: %s",
isc_result_totext(eresult));
}
if (query->tries == 0) {
query_detach(&query);
}
query_detach(&query);
return;
}
@@ -2993,24 +2988,9 @@ start_udp(dig_query_t *query) {
}
}
query->tries = 3;
do {
int local_timeout = timeout * 1000;
if (local_timeout == 0) {
local_timeout = UDP_TIMEOUT * 1000;
}
/*
* On FreeBSD the UDP connect() call sometimes results
* in a spurious transient EADDRINUSE. Try a few more times
* before giving up.
*/
debug("isc_nm_udpconnect(): %d tries left", --query->tries);
result = isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr,
udp_ready, query, local_timeout, 0);
} while (result != ISC_R_SUCCESS && query->tries > 0);
check_result(result, "isc_nm_udpconnect");
isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
(isc_nmiface_t *)&query->sockaddr, udp_ready, query,
(timeout ? timeout : UDP_TIMEOUT) * 1000, 0);
}
/*%

View File

@@ -208,7 +208,6 @@ struct dig_query {
isc_time_t time_recv;
uint64_t byte_count;
isc_timer_t *timer;
uint8_t tries;
isc_tlsctx_t *tlsctx;
};

View File

@@ -597,6 +597,7 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
isc__networker_t *worker = NULL;
int uv_bind_flags = UV_UDP_REUSEADDR;
isc_result_t result = ISC_R_DEFAULT;
int tries = 3;
int r;
REQUIRE(isc__nm_in_netthread());
@@ -642,7 +643,15 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
&(int){ ISC_SEND_BUFFER_SIZE });
#endif
r = isc_uv_udp_connect(&sock->uv_handle.udp, &req->peer.type.sa);
/*
* On FreeBSD the UDP connect() call sometimes results in a
* spurious transient EADDRINUSE. Try a few more times before
* giving up.
*/
do {
r = isc_uv_udp_connect(&sock->uv_handle.udp,
&req->peer.type.sa);
} while (r == UV_EADDRINUSE && --tries > 0);
if (r != 0) {
isc__nm_incstats(sock->mgr,
sock->statsindex[STATID_CONNECTFAIL]);