Skip to content

Commit a60a9b0

Browse files
committed
deps: provide TXT chunk info in c-ares
Provide more information in `ares_txt_reply` to coalesce chunks from the same record into one string. fix #7367
1 parent 3950024 commit a60a9b0

File tree

4 files changed

+22
-6
lines changed

4 files changed

+22
-6
lines changed

deps/cares/include/ares.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,8 @@ struct ares_txt_reply {
520520
struct ares_txt_reply *next;
521521
unsigned char *txt;
522522
size_t length; /* length excludes null termination */
523+
unsigned char record_start; /* 1 - if start of new record
524+
* 0 - if a chunk in the same record */
523525
};
524526

525527
struct ares_naptr_reply {

deps/cares/src/ares_parse_txt_reply.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,6 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
133133
break;
134134
}
135135

136-
++strptr;
137-
138136
/* Allocate storage for this TXT answer appending it to the list */
139137
txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
140138
if (!txt_curr)
@@ -152,13 +150,16 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
152150
}
153151
txt_last = txt_curr;
154152

153+
txt_curr->record_start = strptr == aptr;
155154
txt_curr->length = substr_len;
156155
txt_curr->txt = malloc (substr_len + 1/* Including null byte */);
157156
if (txt_curr->txt == NULL)
158157
{
159158
status = ARES_ENOMEM;
160159
break;
161160
}
161+
162+
++strptr;
162163
memcpy ((char *) txt_curr->txt, strptr, substr_len);
163164

164165
/* Make sure we NULL-terminate */

doc/api/dns.markdown

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,10 @@ attribute (e.g. `[{'priority': 10, 'exchange': 'mx.example.com'},...]`).
9595
## dns.resolveTxt(hostname, callback)
9696

9797
The same as `dns.resolve()`, but only for text queries (`TXT` records).
98-
`addresses` is an array of the text records available for `hostname` (e.g.,
99-
`['v=spf1 ip4:0.0.0.0 ~all']`).
98+
`addresses` is an 2-d array of the text records available for `hostname` (e.g.,
99+
`[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of
100+
one record. Depending on the use case, the could be either joined together or
101+
treated separately.
100102

101103
## dns.resolveSrv(hostname, callback)
102104

src/cares_wrap.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,12 +576,23 @@ class QueryTxtWrap: public QueryWrap {
576576
}
577577

578578
Local<Array> txt_records = Array::New(env()->isolate());
579+
Local<Array> txt_chunk;
579580

580581
ares_txt_reply* current = txt_out;
581-
for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
582+
uint32_t i = 0;
583+
for (uint32_t j = 0; current != NULL; current = current->next) {
582584
Local<String> txt = OneByteString(env()->isolate(), current->txt);
583-
txt_records->Set(i, txt);
585+
// New record found - write out the current chunk
586+
if (current->record_start) {
587+
if (!txt_chunk.IsEmpty())
588+
txt_records->Set(i++, txt_chunk);
589+
txt_chunk = Array::New(env()->isolate());
590+
j = 0;
591+
}
592+
txt_chunk->Set(j++, txt);
584593
}
594+
// Push last chunk
595+
txt_records->Set(i, txt_chunk);
585596

586597
ares_free_data(txt_out);
587598

0 commit comments

Comments
 (0)