MINOR: resolvers: Clean server in a dedicated function when removing a SRV item
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 15 Jun 2021 14:08:48 +0000 (16:08 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 6 Jul 2021 16:14:20 +0000 (18:14 +0200)
A dedicated function is now used to clean up servers when a SRV item becomes
obsolete or when a requester is removed from a resolution. This patch is
mandatory to fix a bug.

(cherry picked from commit 11c6c396560107ac892a553bfa0dada222823b1c)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 5f8ccff67f98efdf8b3e6cb2c02593e4b4aa5b7e)
[cf: Changes applied in src/dns.c instead of src/resolvers.c]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

src/dns.c

index eb58cf3..e95e11b 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -627,6 +627,30 @@ int dns_read_name(unsigned char *buffer, unsigned char *bufend,
        return 0;
 }
 
+/* Cleanup fqdn/port and address of a server attached to a SRV resolution. This
+ * happens when an SRV item is purged or when the server status is considered as
+ * obsolete.
+ *
+ * Must be called with the DNS lock held.
+ */
+static void dns_srvrq_cleanup_srv(struct server *srv)
+{
+       dns_unlink_resolution(srv->dns_requester, 0);
+       HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
+       srvrq_update_srv_status(srv, 1);
+       free(srv->hostname);
+       free(srv->hostname_dn);
+       srv->hostname = NULL;
+       srv->hostname_dn = NULL;
+       srv->hostname_dn_len = 0;
+       memset(&srv->addr, 0, sizeof(srv->addr));
+       srv->svc_port = 0;
+       srv->flags |= SRV_F_NO_RESOLUTION;
+       HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
+       LIST_DEL(&srv->srv_rec_item);
+       LIST_ADDQ(&srv->srvrq->attached_servers, &srv->srv_rec_item);
+}
+
 /* Checks for any obsolete record, also identify any SRV request, and try to
  * find a corresponding server.
 */
@@ -660,22 +684,8 @@ static void dns_check_dns_response(struct dns_resolution *res)
                        }
                        else if (item->type == DNS_RTYPE_SRV) {
                                /* Remove any associated server */
-                               list_for_each_entry_safe(srv, srvback, &item->attached_servers, srv_rec_item) {
-                                       dns_unlink_resolution(srv->dns_requester, 0);
-                                       HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
-                                       srvrq_update_srv_status(srv, 1);
-                                       free(srv->hostname);
-                                       free(srv->hostname_dn);
-                                       srv->hostname = NULL;
-                                       srv->hostname_dn = NULL;
-                                       srv->hostname_dn_len = 0;
-                                       memset(&srv->addr, 0, sizeof(srv->addr));
-                                       srv->svc_port = 0;
-                                       srv->flags |= SRV_F_NO_RESOLUTION;
-                                       HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
-                                       LIST_DEL(&srv->srv_rec_item);
-                                       LIST_ADDQ(&srv->srvrq->attached_servers, &srv->srv_rec_item);
-                               }
+                               list_for_each_entry_safe(srv, srvback, &item->attached_servers, srv_rec_item)
+                                       dns_srvrq_cleanup_srv(srv);
                        }
 
                        LIST_DEL(&item->list);
@@ -1991,22 +2001,8 @@ void dns_detach_from_resolution_answer_items(struct dns_resolution *res,  struct
                list_for_each_entry_safe(item, itemback, &res->response.answer_list, list) {
                        if (item->type == DNS_RTYPE_SRV) {
                                list_for_each_entry_safe(srv, srvback, &item->attached_servers, srv_rec_item) {
-                                       if (srv->srvrq == srvrq) {
-                                               HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
-                                               dns_unlink_resolution(srv->dns_requester, safe);
-                                               srvrq_update_srv_status(srv, 1);
-                                               free(srv->hostname);
-                                               free(srv->hostname_dn);
-                                               srv->hostname = NULL;
-                                               srv->hostname_dn = NULL;
-                                               srv->hostname_dn_len = 0;
-                                               memset(&srv->addr, 0, sizeof(srv->addr));
-                                               srv->svc_port = 0;
-                                               srv->flags |= SRV_F_NO_RESOLUTION;
-                                               HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
-                                               LIST_DEL(&srv->srv_rec_item);
-                                               LIST_ADDQ(&srvrq->attached_servers, &srv->srv_rec_item);
-                                       }
+                                       if (srv->srvrq == srvrq)
+                                               dns_srvrq_cleanup_srv(srv);
                                }
                        }
                }