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;