BUG/MINOR: dns: Don't lock the server lock in snr_check_ip_callback().

snr_check_ip_callback() may be called with the server lock, so don't attempt
to lock it again, instead, make sure the callers always have the lock before
calling it.
This commit is contained in:
Olivier Houchard 2017-11-06 17:30:28 +01:00 committed by Willy Tarreau
parent 55dcdf4c39
commit 283810773a
2 changed files with 12 additions and 4 deletions

View file

@ -1614,7 +1614,13 @@ static void dns_resolve_recv(struct dgram_conn *dgram)
* from the cache */
tmpns = ns;
list_for_each_entry(req, &res->requesters, list) {
struct server *s = objt_server(req->owner);
if (s)
SPIN_LOCK(SERVER_LOCK, &s->lock);
req->requester_cb(req, tmpns);
if (s)
SPIN_UNLOCK(SERVER_LOCK, &s->lock);
tmpns = NULL;
}

View file

@ -3589,6 +3589,8 @@ int snr_update_srv_status(struct server *s, int has_no_ip)
* returns:
* 0 on error
* 1 when no error or safe ignore
*
* Must be called with server lock held
*/
int snr_resolution_cb(struct dns_requester *requester, struct dns_nameserver *nameserver)
{
@ -3694,7 +3696,9 @@ int snr_resolution_error_cb(struct dns_requester *requester, int error_code)
s = objt_server(requester->owner);
if (!s)
return 1;
SPIN_LOCK(SERVER_LOCK, &s->lock);
snr_update_srv_status(s, 0);
SPIN_UNLOCK(SERVER_LOCK, &s->lock);
return 1;
}
@ -3703,6 +3707,8 @@ int snr_resolution_error_cb(struct dns_requester *requester, int error_code)
* which owns <srv> and is up.
* It returns a pointer to the first server found or NULL if <ip> is not yet
* assigned.
*
* Must be called with server lock held
*/
struct server *snr_check_ip_callback(struct server *srv, void *ip, unsigned char *ip_family)
{
@ -3712,8 +3718,6 @@ struct server *snr_check_ip_callback(struct server *srv, void *ip, unsigned char
if (!srv)
return NULL;
SPIN_LOCK(SERVER_LOCK, &srv->lock);
be = srv->proxy;
for (tmpsrv = be->srv; tmpsrv; tmpsrv = tmpsrv->next) {
/* we found the current server is the same, ignore it */
@ -3751,13 +3755,11 @@ struct server *snr_check_ip_callback(struct server *srv, void *ip, unsigned char
(tmpsrv->addr.ss_family == AF_INET6 &&
memcmp(ip, &((struct sockaddr_in6 *)&tmpsrv->addr)->sin6_addr, 16) == 0))) {
SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
return tmpsrv;
}
SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
}
SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
return NULL;
}