MEDIUM: dns: extract options

DNS selection preferences are actually declared inline in the
struct server. There are copied from the server struct to the
dns_resolution struct for each resolution.

Next patchs adds new preferences options, and it is not a good
way to copy all the configuration information before each dns
resolution.

This patch extract the configuration preference from the struct
server and declares a new dedicated struct. Only a pointer to this
new striuict will be copied before each dns resolution.
diff --git a/include/proto/dns.h b/include/proto/dns.h
index 4ccbfa0..170eefa 100644
--- a/include/proto/dns.h
+++ b/include/proto/dns.h
@@ -34,8 +34,8 @@
 uint16_t dns_rnd16(void);
 int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char *dn_name, int dn_name_len);
 int dns_get_ip_from_response(unsigned char *resp, unsigned char *resp_end,
-                             char *dn_name, int dn_name_len, void *currentip,
-                             short currentip_sin_family, int family_priority,
+                             struct dns_resolution *resol, void *currentip,
+                             short currentip_sin_family,
                              void **newip, short *newip_sin_family);
 void dns_resolve_send(struct dgram_conn *dgram);
 void dns_resolve_recv(struct dgram_conn *dgram);
diff --git a/include/types/dns.h b/include/types/dns.h
index ea1a9f9..cf784cd 100644
--- a/include/types/dns.h
+++ b/include/types/dns.h
@@ -140,6 +140,10 @@
 	} counters;
 };
 
+struct dns_options {
+	int family_prio;	/* which IP family should the resolver use when both are returned */
+};
+
 /*
  * resolution structure associated to single server and used to manage name resolution for
  * this server.
@@ -155,7 +159,7 @@
 					/* requester callback, for error management */
 	char *hostname_dn;		/* server hostname in domain name label format */
 	int hostname_dn_len;		/* server domain name label len */
-	int resolver_family_priority;	/* which IP family should the resolver use when both are returned */
+	struct dns_options *opts;       /* IP selection options inherited from the configuration file. */
 	unsigned int last_resolution;	/* time of the lastest valid resolution */
 	unsigned int last_sent_packet;	/* time of the latest DNS packet sent */
 	unsigned int last_status_change;	/* time of the latest DNS resolution status change */
diff --git a/include/types/server.h b/include/types/server.h
index 3e25c34..c04af9c 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -35,6 +35,7 @@
 
 #include <types/connection.h>
 #include <types/counters.h>
+#include <types/dns.h>
 #include <types/freq_ctr.h>
 #include <types/obj_type.h>
 #include <types/proxy.h>
@@ -224,7 +225,7 @@
 	char *resolvers_id;			/* resolvers section used by this server */
 	char *hostname;				/* server hostname */
 	struct dns_resolution *resolution;	/* server name resolution */
-	int resolver_family_priority;		/* which IP family should the resolver use when both are returned */
+	struct dns_options dns_opts;
 
 #ifdef USE_OPENSSL
 	int use_ssl;				/* ssl enabled */
diff --git a/src/checks.c b/src/checks.c
index 2cfb01f..4d3b393 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -2218,8 +2218,8 @@
 	resolution->query_id = query_id;
 	resolution->qid.key = query_id;
 	resolution->step = RSLV_STEP_RUNNING;
-	resolution->resolver_family_priority = s->resolver_family_priority;
-	if (resolution->resolver_family_priority == AF_INET) {
+	resolution->opts = &s->dns_opts;
+	if (resolution->opts->family_prio == AF_INET) {
 		resolution->query_type = DNS_RTYPE_A;
 	} else {
 		resolution->query_type = DNS_RTYPE_AAAA;
diff --git a/src/dns.c b/src/dns.c
index 0d8d305..f43a675 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -102,7 +102,7 @@
 	resolution->qid.key = 0;
 
 	/* default values */
-	if (resolution->resolver_family_priority == AF_INET) {
+	if (resolution->opts->family_prio == AF_INET) {
 		resolution->query_type = DNS_RTYPE_A;
 	} else {
 		resolution->query_type = DNS_RTYPE_AAAA;
@@ -593,12 +593,20 @@
  * returns one of the DNS_UPD_* code
  */
 int dns_get_ip_from_response(unsigned char *resp, unsigned char *resp_end,
-		char *dn_name, int dn_name_len, void *currentip, short currentip_sin_family,
-		int family_priority, void **newip, short *newip_sin_family)
+                             struct dns_resolution *resol, void *currentip,
+                             short currentip_sin_family,
+                             void **newip, short *newip_sin_family)
 {
+	int family_priority;
+	char *dn_name;
+	int dn_name_len;
 	int i, ancount, cnamelen, type, data_len, currentip_found;
 	unsigned char *reader, *cname, *ptr, *newip4, *newip6;
 
+	family_priority = resol->opts->family_prio;
+	dn_name = resol->hostname_dn;
+	dn_name_len = resol->hostname_dn_len;
+
 	cname = *newip = newip4 = newip6 = NULL;
 	cnamelen = currentip_found = 0;
 	*newip_sin_family = AF_UNSPEC;
diff --git a/src/server.c b/src/server.c
index 3a04d22..84dad38 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1017,15 +1017,15 @@
 			newsrv->agent.fall	= curproxy->defsrv.agent.fall;
 			newsrv->agent.health	= newsrv->agent.rise;	/* up, but will fall down at first failure */
 			newsrv->agent.server	= newsrv;
-			newsrv->resolver_family_priority = curproxy->defsrv.resolver_family_priority;
-			if (newsrv->resolver_family_priority == AF_UNSPEC)
-				newsrv->resolver_family_priority = AF_INET6;
+			newsrv->dns_opts.family_prio = curproxy->defsrv.dns_opts.family_prio;
+			if (newsrv->dns_opts.family_prio == AF_UNSPEC)
+				newsrv->dns_opts.family_prio = AF_INET6;
 
 			cur_arg = 3;
 		} else {
 			newsrv = &curproxy->defsrv;
 			cur_arg = 1;
-			newsrv->resolver_family_priority = AF_INET6;
+			newsrv->dns_opts.family_prio = AF_INET6;
 		}
 
 		while (*args[cur_arg]) {
@@ -1079,9 +1079,9 @@
 			}
 			else if (!strcmp(args[cur_arg], "resolve-prefer")) {
 				if (!strcmp(args[cur_arg + 1], "ipv4"))
-					newsrv->resolver_family_priority = AF_INET;
+					newsrv->dns_opts.family_prio = AF_INET;
 				else if (!strcmp(args[cur_arg + 1], "ipv6"))
-					newsrv->resolver_family_priority = AF_INET6;
+					newsrv->dns_opts.family_prio = AF_INET6;
 				else {
 					Alert("parsing [%s:%d]: '%s' expects either ipv4 or ipv6 as argument.\n",
 						file, linenum, args[cur_arg]);
@@ -1746,7 +1746,7 @@
 			}
 
 			if (newsrv->resolution)
-				newsrv->resolution->resolver_family_priority = newsrv->resolver_family_priority;
+				newsrv->resolution->opts = &newsrv->dns_opts;
 
 			newsrv->check.state |= CHK_ST_CONFIGURED | CHK_ST_ENABLED;
 		}
@@ -2625,9 +2625,9 @@
 			goto invalid;
 	}
 
-	ret = dns_get_ip_from_response(response, response_end, resolution->hostname_dn, resolution->hostname_dn_len,
-			serverip, server_sin_family, resolution->resolver_family_priority, &firstip,
-			&firstip_sin_family);
+	ret = dns_get_ip_from_response(response, response_end, resolution,
+	                               serverip, server_sin_family, &firstip,
+	                               &firstip_sin_family);
 
 	switch (ret) {
 		case DNS_UPD_NO:
@@ -2737,8 +2737,8 @@
 		case DNS_RESP_TRUNCATED:
 		case DNS_RESP_ERROR:
 		case DNS_RESP_NO_EXPECTED_RECORD:
-			res_preferred_afinet = resolution->resolver_family_priority == AF_INET && resolution->query_type == DNS_RTYPE_A;
-			res_preferred_afinet6 = resolution->resolver_family_priority == AF_INET6 && resolution->query_type == DNS_RTYPE_AAAA;
+			res_preferred_afinet = resolution->opts->family_prio == AF_INET && resolution->query_type == DNS_RTYPE_A;
+			res_preferred_afinet6 = resolution->opts->family_prio == AF_INET6 && resolution->query_type == DNS_RTYPE_AAAA;
 
 			if ((res_preferred_afinet || res_preferred_afinet6)
 				       || (resolution->try > 0)) {
@@ -2753,7 +2753,7 @@
 				}
 				else {
 					resolution->try -= 1;
-					if (resolution->resolver_family_priority == AF_INET) {
+					if (resolution->opts->family_prio == AF_INET) {
 						resolution->query_type = DNS_RTYPE_A;
 					} else {
 						resolution->query_type = DNS_RTYPE_AAAA;