]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: resolvers: basic TXT record implementation
authorWilliam Lallemand <wlallemand@haproxy.com>
Tue, 24 Mar 2026 10:43:19 +0000 (11:43 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Mon, 30 Mar 2026 16:24:28 +0000 (18:24 +0200)
This patch adds support for TXT records. It allows to get the first
string of a TXT-record which is limited to 255 characters.
The rest of the record is ignored.

include/haproxy/resolvers-t.h
src/resolvers.c

index ace35c510a82443cf5c6fff7865582940337c60e..e89f5b547a20e67c2a3d158a2cd8f97c3f9fb86b 100644 (file)
@@ -72,6 +72,7 @@ extern struct pool_head *resolv_requester_pool;
 /* dns record types (non exhaustive list) */
 #define DNS_RTYPE_A             1       /* IPv4 address */
 #define DNS_RTYPE_CNAME         5       /* canonical name */
+#define DNS_RTYPE_TXT           16      /* TXT */
 #define DNS_RTYPE_AAAA          28      /* IPv6 address */
 #define DNS_RTYPE_SRV           33      /* SRV record */
 #define DNS_RTYPE_OPT           41      /* OPT */
index f48a2bf9bfdabdd255094ba6ed7a1a238f22d644..4cc13179da50c1c5de8a9aa76fe95199f1548047 100644 (file)
@@ -1326,15 +1326,33 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe
                                key = XXH32(reader, answer_record->data_len, answer_record->type);
                                break;
 
+                       case DNS_RTYPE_TXT: {
+                               /* TXT: sequence of [1-byte length | string bytes] *.
+                                * Only the first string is kept, further data is ignored.
+                                */
+                               int slen = (unsigned char)reader[0];
+
+                               if (answer_record->data_len < 1 || 1 + slen > answer_record->data_len)
+                                       goto invalid_resp;
+                               offset = answer_record->data_len;
+                               memcpy(answer_record->data.target, reader + 1, slen);
+                               answer_record->data.target[slen] = 0;
+                               answer_record->data_len = slen;
+                               key = XXH32(answer_record->data.target, slen, answer_record->type);
+                               break;
+                       }
+
                } /* switch (record type) */
 
                /* Increment the counter for number of records saved into our
                 * local response */
                nb_saved_records++;
 
-               /* Move forward answer_record->data_len for analyzing next
-                * record in the response */
-               reader += ((answer_record->type == DNS_RTYPE_SRV)
+               /* Move forward past the record data. For SRV and TXT, offset holds
+                * the wire data length
+                */
+               reader += ((answer_record->type == DNS_RTYPE_SRV ||
+                           answer_record->type == DNS_RTYPE_TXT)
                           ? offset
                           : answer_record->data_len);
 
@@ -1370,6 +1388,12 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe
                                }
                                 break;
 
+                       case DNS_RTYPE_TXT:
+                               if (answer_record->data_len == tmp_record->data_len &&
+                                   memcmp(answer_record->data.target, tmp_record->data.target, answer_record->data_len) == 0)
+                                       found = 1;
+                               break;
+
                        default:
                                break;
                        }