From: Olivier Houchard Date: Mon, 8 Jan 2018 15:28:57 +0000 (+0100) Subject: MINOR: dns: Handle SRV record weight correctly. X-Git-Tag: v1.9-dev1~523 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ec2db9725fb54a76c726c5b8cc502071c575d28;p=thirdparty%2Fhaproxy.git MINOR: dns: Handle SRV record weight correctly. A SRV record weight can range from 0 to 65535, while haproxy weight goes from 0 to 256, so we have to divide it by 256 before handing it to haproxy. Also, a SRV record with a weight of 0 doesn't mean the server shouldn't be used, so use a minimum weight of 1. This should probably be backported to 1.8. --- diff --git a/include/types/dns.h b/include/types/dns.h index b1f068a613..9b1d08df7f 100644 --- a/include/types/dns.h +++ b/include/types/dns.h @@ -143,7 +143,7 @@ struct dns_answer_item { int16_t class; /* query class */ int32_t ttl; /* response TTL */ int16_t priority; /* SRV type priority */ - int16_t weight; /* SRV type weight */ + uint16_t weight; /* SRV type weight */ int16_t port; /* SRV type port */ int16_t data_len; /* number of bytes in target below */ struct sockaddr address; /* IPv4 or IPv6, network format */ diff --git a/src/dns.c b/src/dns.c index fceef2e480..a957710edb 100644 --- a/src/dns.c +++ b/src/dns.c @@ -522,10 +522,16 @@ static void dns_check_dns_response(struct dns_resolution *res) if (srv->srvrq == srvrq && srv->svc_port == item->port && item->data_len == srv->hostname_dn_len && !memcmp(srv->hostname_dn, item->target, item->data_len)) { - if (srv->uweight != item->weight) { + int ha_weight; + + /* Make sure weight is at least 1, so + * that the server will be used. + */ + ha_weight = item->weight / 256 + 1; + if (srv->uweight != ha_weight) { char weight[9]; - snprintf(weight, sizeof(weight), "%d", item->weight); + snprintf(weight, sizeof(weight), "%d", ha_weight); server_parse_weight_change_request(srv, weight); } HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock); @@ -547,6 +553,7 @@ static void dns_check_dns_response(struct dns_resolution *res) if (srv) { const char *msg = NULL; char weight[9]; + int ha_weight; char hostname[DNS_MAX_NAME_SIZE]; if (dns_dn_label_to_str(item->target, item->data_len+1, @@ -563,7 +570,13 @@ static void dns_check_dns_response(struct dns_resolution *res) if ((srv->check.state & CHK_ST_CONFIGURED) && !(srv->flags & SRV_F_CHECKPORT)) srv->check.port = item->port; - snprintf(weight, sizeof(weight), "%d", item->weight); + + /* Make sure weight is at least 1, so + * that the server will be used. + */ + ha_weight = item->weight / 256 + 1; + + snprintf(weight, sizeof(weight), "%d", ha_weight); server_parse_weight_change_request(srv, weight); HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock); }