Skip to content

Commit db66816

Browse files
richaasalfredh
authored andcommitted
DNS TXT resource record support (#219)
* Added DNS TXT resource record * dns/txt: encode at least one character string * rr encode: improve maximum rdata length check
1 parent b2953f7 commit db66816

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

include/re_dns.h

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum {
4040
DNS_TYPE_SOA = 0x0006,
4141
DNS_TYPE_PTR = 0x000c,
4242
DNS_TYPE_MX = 0x000f,
43+
DNS_TYPE_TXT = 0x0010,
4344
DNS_TYPE_AAAA = 0x001c,
4445
DNS_TYPE_SRV = 0x0021,
4546
DNS_TYPE_NAPTR = 0x0023,
@@ -109,6 +110,9 @@ struct dnsrr {
109110
uint16_t pref;
110111
char *exchange;
111112
} mx;
113+
struct {
114+
char *data;
115+
} txt;
112116
struct {
113117
uint8_t addr[16];
114118
} aaaa;

src/dns/rr.c

+64-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ static void rr_destructor(void *data)
4343
mem_deref(rr->rdata.mx.exchange);
4444
break;
4545

46+
case DNS_TYPE_TXT:
47+
mem_deref(rr->rdata.txt.data);
48+
break;
49+
4650
case DNS_TYPE_SRV:
4751
mem_deref(rr->rdata.srv.target);
4852
break;
@@ -83,8 +87,8 @@ int dns_rr_encode(struct mbuf *mb, const struct dnsrr *rr, int64_t ttl_offs,
8387
struct hash *ht_dname, size_t start)
8488
{
8589
uint32_t ttl;
86-
uint16_t len;
87-
size_t start_rdata;
90+
size_t start_rdata, dlen, len;
91+
char *ptr;
8892
int err = 0;
8993

9094
if (!mb || !rr)
@@ -139,6 +143,21 @@ int dns_rr_encode(struct mbuf *mb, const struct dnsrr *rr, int64_t ttl_offs,
139143
ht_dname, start, true);
140144
break;
141145

146+
case DNS_TYPE_TXT:
147+
ptr = rr->rdata.txt.data;
148+
dlen = str_len(rr->rdata.txt.data);
149+
150+
do {
151+
uint8_t slen = min(dlen, 0xff);
152+
153+
err |= mbuf_write_u8(mb, slen);
154+
err |= mbuf_write_mem(mb, (uint8_t *)ptr, slen);
155+
156+
ptr += slen;
157+
dlen -= slen;
158+
} while (dlen > 0);
159+
break;
160+
142161
case DNS_TYPE_AAAA:
143162
err |= mbuf_write_mem(mb, rr->rdata.aaaa.addr, 16);
144163
break;
@@ -167,6 +186,10 @@ int dns_rr_encode(struct mbuf *mb, const struct dnsrr *rr, int64_t ttl_offs,
167186
}
168187

169188
len = mb->pos - start_rdata;
189+
190+
if (len > 0xffff)
191+
return EOVERFLOW;
192+
170193
mb->pos = start_rdata - 2;
171194
err |= mbuf_write_u16(mb, htons(len));
172195
mb->pos += len;
@@ -188,6 +211,8 @@ int dns_rr_decode(struct mbuf *mb, struct dnsrr **rr, size_t start)
188211
{
189212
int err = 0;
190213
struct dnsrr *lrr;
214+
uint16_t rdlen;
215+
char *ptr;
191216

192217
if (!mb || !rr)
193218
return EINVAL;
@@ -272,6 +297,31 @@ int dns_rr_decode(struct mbuf *mb, struct dnsrr **rr, size_t start)
272297

273298
break;
274299

300+
case DNS_TYPE_TXT:
301+
ptr = lrr->rdata.txt.data = mem_alloc(lrr->rdlen + 1, NULL);
302+
if (!lrr->rdata.txt.data) {
303+
err = ENOMEM;
304+
goto error;
305+
}
306+
307+
rdlen = lrr->rdlen;
308+
309+
while (rdlen > 0) {
310+
311+
uint8_t len = mbuf_read_u8(mb);
312+
313+
if (len > --rdlen)
314+
goto fmerr;
315+
316+
mbuf_read_mem(mb, (uint8_t *)ptr, len);
317+
318+
ptr += len;
319+
rdlen -= len;
320+
}
321+
322+
*ptr = '\0';
323+
break;
324+
275325
case DNS_TYPE_AAAA:
276326
if (lrr->rdlen != 16)
277327
goto fmerr;
@@ -429,6 +479,13 @@ bool dns_rr_cmp(const struct dnsrr *rr1, const struct dnsrr *rr2, bool rdata)
429479

430480
break;
431481

482+
case DNS_TYPE_TXT:
483+
if (str_casecmp(rr1->rdata.txt.data,
484+
rr2->rdata.txt.data))
485+
return false;
486+
487+
break;
488+
432489
case DNS_TYPE_AAAA:
433490
if (memcmp(rr1->rdata.aaaa.addr, rr2->rdata.aaaa.addr, 16))
434491
return false;
@@ -504,6 +561,7 @@ const char *dns_rr_typename(uint16_t type)
504561
case DNS_TYPE_SOA: return "SOA";
505562
case DNS_TYPE_PTR: return "PTR";
506563
case DNS_TYPE_MX: return "MX";
564+
case DNS_TYPE_TXT: return "TXT";
507565
case DNS_TYPE_AAAA: return "AAAA";
508566
case DNS_TYPE_SRV: return "SRV";
509567
case DNS_TYPE_NAPTR: return "NAPTR";
@@ -598,6 +656,10 @@ int dns_rr_print(struct re_printf *pf, const struct dnsrr *rr)
598656
rr->rdata.mx.exchange);
599657
break;
600658

659+
case DNS_TYPE_TXT:
660+
err |= re_hprintf(pf, "\"%s\"", rr->rdata.txt.data);
661+
break;
662+
601663
case DNS_TYPE_AAAA:
602664
sa_set_in6(&sa, rr->rdata.aaaa.addr, 0);
603665
err |= re_hprintf(pf, "%j", &sa);

0 commit comments

Comments
 (0)