You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

158 lines
5.8 KiB

commit c1bfcd002f54d1d84a99282d13f875c2649f3d70
Author: Baptiste Assmann <bedis9@gmail.com>
Date: Fri Jun 22 15:04:43 2018 +0200
MINOR: dns: new DNS options to allow/prevent IP address duplication
By default, HAProxy's DNS resolution at runtime ensure that there is no
IP address duplication in a backend (for servers being resolved by the
same hostname).
There are a few cases where people want, on purpose, to disable this
feature.
This patch introduces a couple of new server side options for this purpose:
"resolve-opts allow-dup-ip" or "resolve-opts prevent-dup-ip".
(cherry picked from commit 8e2d9430c0562ed74276d7f58e92706c384c0a36)
[wt: this is backported to 1.8 upon request from Baptiste because it offers
the option to revert to 1.7 behaviour, which some people depend on. The
address deduplication used on 1.8 apparently is not suited to everyone]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 011533a0..1973bbf2 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -11623,6 +11623,40 @@ rise <count>
after <count> consecutive successful health checks. This value defaults to 2
if unspecified. See also the "check", "inter" and "fall" parameters.
+resolve-opts <option>,<option>,...
+ Comma separated list of options to apply to DNS resolution linked to this
+ server.
+
+ Available options:
+
+ * allow-dup-ip
+ By default, HAProxy prevents IP address duplication in a backend when DNS
+ resolution at runtime is in operation.
+ That said, for some cases, it makes sense that two servers (in the same
+ backend, being resolved by the same FQDN) have the same IP address.
+ For such case, simply enable this option.
+ This is the opposite of prevent-dup-ip.
+
+ * prevent-dup-ip
+ Ensure HAProxy's default behavior is enforced on a server: prevent re-using
+ an IP address already set to a server in the same backend and sharing the
+ same fqdn.
+ This is the opposite of allow-dup-ip.
+
+ Example:
+ backend b_myapp
+ default-server init-addr none resolvers dns
+ server s1 myapp.example.com:80 check resolve-opts allow-dup-ip
+ server s2 myapp.example.com:81 check resolve-opts allow-dup-ip
+
+ With the option allow-dup-ip set:
+ * if the nameserver returns a single IP address, then both servers will use
+ it
+ * If the nameserver returns 2 IP addresses, then each server will pick up a
+ different address
+
+ Default value: not set
+
resolve-prefer <family>
When DNS resolution is enabled for a server and multiple IP addresses from
different families are returned, HAProxy will prefer using an IP address
diff --git a/include/types/dns.h b/include/types/dns.h
index 9b1d08df..488d3996 100644
--- a/include/types/dns.h
+++ b/include/types/dns.h
@@ -245,6 +245,8 @@ struct dns_options {
} mask;
} pref_net[SRV_MAX_PREF_NET];
int pref_net_nb; /* The number of registered prefered networks. */
+ int accept_duplicate_ip; /* flag to indicate whether the associated object can use an IP address
+ already set to an other object of the same group */
};
/* Resolution structure associated to single server and used to manage name
diff --git a/src/dns.c b/src/dns.c
index d8388ef1..b31000a2 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -965,8 +965,10 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
int currentip_sel;
int j;
int score, max_score;
+ int allowed_duplicated_ip;
family_priority = dns_opts->family_prio;
+ allowed_duplicated_ip = dns_opts->accept_duplicate_ip;
*newip = newip4 = newip6 = NULL;
currentip_found = 0;
*newip_sin_family = AF_UNSPEC;
@@ -1030,7 +1032,9 @@ int dns_get_ip_from_response(struct dns_response_packet *dns_p,
* member of a group. If not, the score should be incremented
* by 2. */
if (owner && snr_check_ip_callback(owner, ip, &ip_type)) {
- continue;
+ if (!allowed_duplicated_ip) {
+ continue;
+ }
} else {
score += 2;
}
diff --git a/src/server.c b/src/server.c
index fbed6cd4..36a05e27 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1506,6 +1506,7 @@ static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmp
if (src->resolvers_id != NULL)
srv->resolvers_id = strdup(src->resolvers_id);
srv->dns_opts.family_prio = src->dns_opts.family_prio;
+ srv->dns_opts.accept_duplicate_ip = src->dns_opts.accept_duplicate_ip;
if (srv->dns_opts.family_prio == AF_UNSPEC)
srv->dns_opts.family_prio = AF_INET6;
memcpy(srv->dns_opts.pref_net,
@@ -2044,6 +2045,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
newsrv = &curproxy->defsrv;
cur_arg = 1;
newsrv->dns_opts.family_prio = AF_INET6;
+ newsrv->dns_opts.accept_duplicate_ip = 0;
}
while (*args[cur_arg]) {
@@ -2139,6 +2141,31 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
newsrv->resolvers_id = strdup(args[cur_arg + 1]);
cur_arg += 2;
}
+ else if (!strcmp(args[cur_arg], "resolve-opts")) {
+ char *p, *end;
+
+ for (p = args[cur_arg + 1]; *p; p = end) {
+ /* cut on next comma */
+ for (end = p; *end && *end != ','; end++);
+ if (*end)
+ *(end++) = 0;
+
+ if (!strcmp(p, "allow-dup-ip")) {
+ newsrv->dns_opts.accept_duplicate_ip = 1;
+ }
+ else if (!strcmp(p, "prevent-dup-ip")) {
+ newsrv->dns_opts.accept_duplicate_ip = 0;
+ }
+ else {
+ ha_alert("parsing [%s:%d]: '%s' : unknown resolve-opts option '%s', supported methods are 'allow-dup-ip' and 'prevent-dup-ip'.\n",
+ file, linenum, args[cur_arg], p);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ }
+
+ cur_arg += 2;
+ }
else if (!strcmp(args[cur_arg], "resolve-prefer")) {
if (!strcmp(args[cur_arg + 1], "ipv4"))
newsrv->dns_opts.family_prio = AF_INET;