BUG/MINOR: resolvers: Always attach server on matching record on resolution
On A/AAAA resolution, for a given server, if a record is matching, we must
always attach the server to this record. Before it was only done if the
server IP was not the same than the record one. However, it is a problem if
the server IP was not set for a previous resolution. From the libc during
startup for instance. In this case, the server IP is not updated and the
server is not attached to any record. It remains in this state while a
matching record is found in the DNS response. It is especially a problem
when the resolution is used for server-templates.
This bug was introduced by the commit bd78c912f ("MEDIUM: resolvers: add a
ref on server to the used A/AAAA answer item").
This patch should solve the issue #1305. It must be backported to all
versions containing the above commit.
(cherry picked from commit d7bb23490c1a71542c7e98b7c44d92df081c7e52)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/resolvers.c b/src/resolvers.c
index 672bde7..5c3bbdd 100644
--- a/src/resolvers.c
+++ b/src/resolvers.c
@@ -1578,8 +1578,6 @@
*newip = newip6;
*newip_sin_family = AF_INET6;
}
- if (!currentip_found)
- goto not_found;
}
/* Case when the caller looks first for an IPv6 address */
else if (family_priority == AF_INET6) {
@@ -1591,8 +1589,6 @@
*newip = newip4;
*newip_sin_family = AF_INET;
}
- if (!currentip_found)
- goto not_found;
}
/* Case when the caller have no preference (we prefer IPv6) */
else if (family_priority == AF_UNSPEC) {
@@ -1604,17 +1600,11 @@
*newip = newip4;
*newip_sin_family = AF_INET;
}
- if (!currentip_found)
- goto not_found;
}
- /* No reason why we should change the server's IP address */
- return RSLV_UPD_NO;
-
- not_found:
-
/* the ip of this record was chosen for the server */
if (owner && found_record) {
+ LIST_DEL_INIT(&owner->ip_rec_item);
LIST_APPEND(&found_record->attached_servers, &owner->ip_rec_item);
}
@@ -1625,7 +1615,8 @@
LIST_APPEND(&r_res->answer_list, &record->list);
break;
}
- return RSLV_UPD_SRVIP_NOT_FOUND;
+
+ return (currentip_found ? RSLV_UPD_NO : RSLV_UPD_SRVIP_NOT_FOUND);
}
/* Turns a domain name label into a string.