MINOR: resolvers: basic TXT record implementation

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.
This commit is contained in:
William Lallemand 2026-03-24 11:43:19 +01:00
parent 418f0c0bbe
commit 56b74b7ea2
2 changed files with 28 additions and 3 deletions

View 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 */

View 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;
}