retry isc_nm_udpconnect() if it fails
On FreeBSD, we sometimes see spurious transient EADDRINUSE errors when connecting to a UDP socket. We now try a few times to ensure the error is real before giving up. This commit also fixes a memory leak that occurred if an error was encountered in isc__nm_async_udpconnect().
This commit is contained in:
@@ -2918,7 +2918,8 @@ static void
|
||||
start_udp(dig_query_t *query) {
|
||||
dig_lookup_t *l = NULL;
|
||||
isc_result_t result;
|
||||
dig_query_t *next;
|
||||
dig_query_t *next = NULL;
|
||||
int i = 0;
|
||||
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
@@ -2971,9 +2972,16 @@ start_udp(dig_query_t *query) {
|
||||
}
|
||||
}
|
||||
|
||||
result = isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr, udp_ready,
|
||||
query, 0);
|
||||
do {
|
||||
/*
|
||||
* On FreeBSD the UDP connect() call sometimes results
|
||||
* in a spurious transient EADDRINUSE. Try a few more times
|
||||
* before giving up.
|
||||
*/
|
||||
result = isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr,
|
||||
udp_ready, query, 0);
|
||||
} while (result != ISC_R_SUCCESS && i++ < 2);
|
||||
check_result(result, "isc_nm_udpconnect");
|
||||
}
|
||||
|
||||
|
||||
@@ -607,7 +607,6 @@ isc__nm_async_udpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
uv_udp_init(&worker->loop, &sock->uv_handle.udp);
|
||||
uv_handle_set_data(&sock->uv_handle.handle, NULL);
|
||||
uv_handle_set_data(&sock->uv_handle.handle, sock);
|
||||
handle = isc__nmhandle_get(sock, &ievent->peer, &sock->iface->addr);
|
||||
|
||||
r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
|
||||
if (r != 0) {
|
||||
@@ -654,16 +653,17 @@ isc__nm_async_udpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
atomic_store(&sock->connected, true);
|
||||
sock->result = ISC_R_SUCCESS;
|
||||
|
||||
done:
|
||||
cb = sock->connect_cb;
|
||||
cbarg = sock->connect_cbarg;
|
||||
|
||||
handle = isc__nmhandle_get(sock, &ievent->peer, &sock->iface->addr);
|
||||
cb(handle, sock->result, cbarg);
|
||||
|
||||
LOCK(&sock->lock);
|
||||
SIGNAL(&sock->cond);
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
done:
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
@@ -743,10 +743,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
||||
UNLOCK(&sock->lock);
|
||||
}
|
||||
|
||||
if (sock->result != ISC_R_SUCCESS) {
|
||||
result = sock->result;
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
sock->result = result;
|
||||
|
||||
isc__nmsocket_detach(&tmp);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user