From: Thierry Fournier Date: Wed, 17 Feb 2016 20:25:09 +0000 (+0100) Subject: MEDIUM: dns: extract options X-Git-Tag: v1.7-dev2~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ada348459f7f647e896317014bb99583d14f33a4;p=thirdparty%2Fhaproxy.git 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 4ccbfa0c7b..170eefa522 100644 --- a/include/proto/dns.h +++ b/include/proto/dns.h @@ -34,8 +34,8 @@ int dns_init_resolvers(void); 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 ea1a9f901a..cf784cd1d6 100644 --- a/include/types/dns.h +++ b/include/types/dns.h @@ -140,6 +140,10 @@ struct dns_nameserver { } 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 @@ struct dns_resolution { /* 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 3e25c344c0..c04af9c3e1 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -224,7 +225,7 @@ struct server { 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 2cfb01f6a5..4d3b39345c 100644 --- a/src/checks.c +++ b/src/checks.c @@ -2218,8 +2218,8 @@ int trigger_resolution(struct server *s) 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 0d8d305c6d..f43a675832 100644 --- a/src/dns.c +++ b/src/dns.c @@ -102,7 +102,7 @@ void dns_reset_resolution(struct dns_resolution *resolution) 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 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char * * 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 3a04d22f6a..84dad38e18 100644 --- a/src/server.c +++ b/src/server.c @@ -1017,15 +1017,15 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr 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 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr } 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 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr } 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 @@ int snr_resolution_cb(struct dns_resolution *resolution, struct dns_nameserver * 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 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code) 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 @@ int snr_resolution_error_cb(struct dns_resolution *resolution, int error_code) } 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;