Skip to content

Commit

Permalink
deps: provide TXT chunk info in c-ares
Browse files Browse the repository at this point in the history
Provide more information in `ares_txt_reply` to coalesce chunks from the
same record into one string.

fix #7367
  • Loading branch information
indutny committed Apr 24, 2014
1 parent 3950024 commit a60a9b0
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 6 deletions.
2 changes: 2 additions & 0 deletions deps/cares/include/ares.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,8 @@ struct ares_txt_reply {
struct ares_txt_reply *next;
unsigned char *txt;
size_t length; /* length excludes null termination */
unsigned char record_start; /* 1 - if start of new record
* 0 - if a chunk in the same record */
};

struct ares_naptr_reply {
Expand Down
5 changes: 3 additions & 2 deletions deps/cares/src/ares_parse_txt_reply.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
break;
}

++strptr;

/* Allocate storage for this TXT answer appending it to the list */
txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
if (!txt_curr)
Expand All @@ -152,13 +150,16 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
}
txt_last = txt_curr;

txt_curr->record_start = strptr == aptr;
txt_curr->length = substr_len;
txt_curr->txt = malloc (substr_len + 1/* Including null byte */);
if (txt_curr->txt == NULL)
{
status = ARES_ENOMEM;
break;
}

++strptr;
memcpy ((char *) txt_curr->txt, strptr, substr_len);

/* Make sure we NULL-terminate */
Expand Down
6 changes: 4 additions & 2 deletions doc/api/dns.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ attribute (e.g. `[{'priority': 10, 'exchange': 'mx.example.com'},...]`).
## dns.resolveTxt(hostname, callback)

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

## dns.resolveSrv(hostname, callback)

Expand Down
15 changes: 13 additions & 2 deletions src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,23 @@ class QueryTxtWrap: public QueryWrap {
}

Local<Array> txt_records = Array::New(env()->isolate());
Local<Array> txt_chunk;

ares_txt_reply* current = txt_out;
for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
uint32_t i = 0;
for (uint32_t j = 0; current != NULL; current = current->next) {
Local<String> txt = OneByteString(env()->isolate(), current->txt);
txt_records->Set(i, txt);
// New record found - write out the current chunk
if (current->record_start) {
if (!txt_chunk.IsEmpty())
txt_records->Set(i++, txt_chunk);
txt_chunk = Array::New(env()->isolate());
j = 0;
}
txt_chunk->Set(j++, txt);
}
// Push last chunk
txt_records->Set(i, txt_chunk);

ares_free_data(txt_out);

Expand Down

0 comments on commit a60a9b0

Please sign in to comment.