]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: dns: Don't try to get the server lock if it's already held.
authorOlivier Houchard <ohouchard@haproxy.com>
Mon, 6 Nov 2017 14:15:04 +0000 (15:15 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 6 Nov 2017 17:34:24 +0000 (18:34 +0100)
dns_link_resolution() can be called with the server lock already held, so
don't attempt to lock it again in that case.

include/proto/dns.h
src/dns.c
src/server.c

index c3e3846dc0b62b28d2dc53b70cee2f1a9d6013ce..3ad79c3a459df7b69ba3c43b8bc330ef4e3ebc2d 100644 (file)
@@ -40,7 +40,7 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
                              void **newip, short *newip_sin_family,
                              void *owner);
 
-int dns_link_resolution(void *requester, int requester_type);
+int dns_link_resolution(void *requester, int requester_type, int requester_locked);
 void dns_unlink_resolution(struct dns_requester *requester);
 void dns_trigger_resolution(struct dns_requester *requester);
 
index 6b87460908452e7958f4283b5bee443107066491..1d12c842109b538b8185205af7c28af25208ea78 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -550,8 +550,10 @@ static void dns_check_dns_response(struct dns_resolution *res)
                                char hostname[DNS_MAX_NAME_SIZE];
 
                                if (dns_dn_label_to_str(item->target, item->data_len+1,
-                                                       hostname, DNS_MAX_NAME_SIZE) == -1)
+                                                       hostname, DNS_MAX_NAME_SIZE) == -1) {
+                                       SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
                                        continue;
+                               }
                                msg = update_server_fqdn(srv, hostname, "SRV record", 1);
                                if (msg)
                                        send_log(srv->proxy, LOG_NOTICE, "%s", msg);
@@ -1307,7 +1309,7 @@ static void dns_free_resolution(struct dns_resolution *resolution)
 /* Links a requester (a server or a dns_srvrq) with a resolution. It returns 0
  * on success, -1 otherwise.
  */
-int dns_link_resolution(void *requester, int requester_type)
+int dns_link_resolution(void *requester, int requester_type, int requester_locked)
 {
        struct dns_resolution *res = NULL;
        struct dns_requester  *req;
@@ -1345,10 +1347,12 @@ int dns_link_resolution(void *requester, int requester_type)
                goto err;
 
        if (srv) {
-               SPIN_LOCK(SERVER_LOCK, &srv->lock);
+               if (!requester_locked)
+                       SPIN_LOCK(SERVER_LOCK, &srv->lock);
                if (srv->dns_requester == NULL) {
                        if ((req = calloc(1, sizeof(*req))) == NULL) {
-                               SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
+                               if (!requester_locked)
+                                       SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
                                goto err;
                        }
                        req->owner         = &srv->obj_type;
@@ -1356,7 +1360,8 @@ int dns_link_resolution(void *requester, int requester_type)
                }
                else
                        req = srv->dns_requester;
-               SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
+               if (!requester_locked)
+                       SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
        }
        else if (srvrq) {
                if (srvrq->dns_requester == NULL) {
@@ -1905,14 +1910,14 @@ static int dns_finalize_config(void)
 
                        if (srv->srvrq && !srv->srvrq->resolvers) {
                                srv->srvrq->resolvers = srv->resolvers;
-                               if (dns_link_resolution(srv->srvrq, OBJ_TYPE_SRVRQ) == -1) {
+                               if (dns_link_resolution(srv->srvrq, OBJ_TYPE_SRVRQ, 0) == -1) {
                                        Alert("config : %s '%s' : unable to set DNS resolution for server '%s'.\n",
                                              proxy_type_str(px), px->id, srv->id);
                                        err_code |= (ERR_ALERT|ERR_ABORT);
                                        continue;
                                }
                        }
-                       if (dns_link_resolution(srv, OBJ_TYPE_SERVER) == -1) {
+                       if (dns_link_resolution(srv, OBJ_TYPE_SERVER, 0) == -1) {
                                Alert("config : %s '%s', unable to set DNS resolution for server '%s'.\n",
                                      proxy_type_str(px), px->id, srv->id);
                                err_code |= (ERR_ALERT|ERR_ABORT);
index ed78ca52d39d336eaa889c377e2f81f46c22c3e1..adc9fd40ce5ea55e9217281130c81c69ab20e981 100644 (file)
@@ -3818,7 +3818,7 @@ int srv_set_fqdn(struct server *srv, const char *hostname, int dns_locked)
        if (!srv->hostname || !srv->hostname_dn)
                goto err;
 
-       if (dns_link_resolution(srv, OBJ_TYPE_SERVER) == -1)
+       if (dns_link_resolution(srv, OBJ_TYPE_SERVER, 1) == -1)
                goto err;
 
   end: