All servers of a proxy using the same SRV name share the same SRV request
(srvrq), which is linked to the resolvers section of the first server
found with a "resolvers" keyword. When another server of the same proxy
uses the same SRV name with a different resolvers section, the SRV
responses are processed by the first section under its own lock, and
resolv_check_response() updates all attached servers from there, calling
srv_update_fqdn(), resolv_link_resolution() and _resolv_unlink_resolution()
on servers whose resolutions belong to the other section, without holding
this other section's lock, while its task may run on another thread. This
can corrupt this section's resolution lists. In addition, the second
section's settings (timeouts, nameservers) are silently ignored for the
SRV record.
Such a configuration is accepted without any warning:
backend be
server-template a 2 _http._tcp.svc.test resolvers r1 init-addr none
server-template c 2 _http._tcp.svc.test resolvers r2 init-addr none
Since there's no valid use case for this, let's report an error when a
server uses an SRV record already used with another resolvers section in
the same proxy.
The SRV request sharing was introduced in 1.8 by commit
67957bd59
("MAJOR: dns: Refactor the DNS code"). This should be backported to all
stable branches.
continue;
}
}
+ else if (srv->srvrq->resolvers != srv->resolvers) {
+ /* the SRV request is shared by all servers of
+ * the proxy using the same SRV name, and the
+ * servers are updated under its resolvers' lock.
+ */
+ ha_alert("%s '%s', server '%s': all servers using SRV record '%s' must use the same resolvers section ('%s' was already used).\n",
+ proxy_type_str(px), px->id, srv->id, srv->srvrq->name, srv->srvrq->resolvers->id);
+ err_code |= (ERR_ALERT|ERR_ABORT);
+ continue;
+ }
srv->srvrq_check = task_new_anywhere();
if (!srv->srvrq_check) {