|
|
- 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;
|