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.
diff --git a/src/dns.c b/src/dns.c
index 1d12c84..0f93f3c 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1614,7 +1614,13 @@
* 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;
}
diff --git a/src/server.c b/src/server.c
index adc9fd4..1a78fb3 100644
--- a/src/server.c
+++ b/src/server.c
@@ -3589,6 +3589,8 @@
* 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 @@
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 @@
* 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 @@
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 @@
(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;
}