Hi,

The attached patch attempts to map SRV record weight to haproxy weight 
correctly,
SRV weight goes from 0 to 65536 while haproxy uses 0 to 256, so we have to
divide it by 256, and a SRV weight of 0 doesn't mean the server shouldn't be
used, so we use a minimum weight of 1.

Regards,

Olivier
>From 8e8ab23223274ac75fdf1cfe2847337133fd59d2 Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Mon, 8 Jan 2018 16:28:57 +0100
Subject: [PATCH] MINOR: Handle SRV record weight correctly.

A SRV record weight can range from 0 to 65535, while haproxy weight goes
from 0 to 255, 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.
---
 include/types/dns.h |  2 +-
 src/dns.c           | 21 ++++++++++++++++++---
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/types/dns.h b/include/types/dns.h
index b1f068a61..9b1d08df7 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 fceef2e48..22af18dc9 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -522,10 +522,17 @@ 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;
+
+                                       /* We still want to use a 0 weight 
server */
+                                       if (item->weight < 256)
+                                               ha_weight = 1;
+                                       else
+                                               ha_weight = item->weight / 256;
+                                       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 +554,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 +571,14 @@ 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);
+
+                               /* We still want to use a 0 weight server */
+                               if (item->weight < 256)
+                                       ha_weight = 1;
+                               else
+                                       ha_weight = item->weight / 256;
+
+                               snprintf(weight, sizeof(weight), "%d", 
ha_weight);
                                server_parse_weight_change_request(srv, weight);
                                HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
                        }
-- 
2.14.3

Reply via email to