Browse Source

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
v0.11.13-release
Fedor Indutny 11 years ago
parent
commit
a60a9b0dbd
  1. 2
      deps/cares/include/ares.h
  2. 5
      deps/cares/src/ares_parse_txt_reply.c
  3. 6
      doc/api/dns.markdown
  4. 15
      src/cares_wrap.cc

2
deps/cares/include/ares.h

@ -520,6 +520,8 @@ struct ares_txt_reply {
struct ares_txt_reply *next; struct ares_txt_reply *next;
unsigned char *txt; unsigned char *txt;
size_t length; /* length excludes null termination */ 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 { struct ares_naptr_reply {

5
deps/cares/src/ares_parse_txt_reply.c

@ -133,8 +133,6 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
break; break;
} }
++strptr;
/* Allocate storage for this TXT answer appending it to the list */ /* Allocate storage for this TXT answer appending it to the list */
txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY); txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
if (!txt_curr) if (!txt_curr)
@ -152,6 +150,7 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
} }
txt_last = txt_curr; txt_last = txt_curr;
txt_curr->record_start = strptr == aptr;
txt_curr->length = substr_len; txt_curr->length = substr_len;
txt_curr->txt = malloc (substr_len + 1/* Including null byte */); txt_curr->txt = malloc (substr_len + 1/* Including null byte */);
if (txt_curr->txt == NULL) if (txt_curr->txt == NULL)
@ -159,6 +158,8 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
status = ARES_ENOMEM; status = ARES_ENOMEM;
break; break;
} }
++strptr;
memcpy ((char *) txt_curr->txt, strptr, substr_len); memcpy ((char *) txt_curr->txt, strptr, substr_len);
/* Make sure we NULL-terminate */ /* Make sure we NULL-terminate */

6
doc/api/dns.markdown

@ -95,8 +95,10 @@ attribute (e.g. `[{'priority': 10, 'exchange': 'mx.example.com'},...]`).
## dns.resolveTxt(hostname, callback) ## dns.resolveTxt(hostname, callback)
The same as `dns.resolve()`, but only for text queries (`TXT` records). 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., `addresses` is an 2-d array of the text records available for `hostname` (e.g.,
`['v=spf1 ip4:0.0.0.0 ~all']`). `[ ['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) ## dns.resolveSrv(hostname, callback)

15
src/cares_wrap.cc

@ -576,12 +576,23 @@ class QueryTxtWrap: public QueryWrap {
} }
Local<Array> txt_records = Array::New(env()->isolate()); Local<Array> txt_records = Array::New(env()->isolate());
Local<Array> txt_chunk;
ares_txt_reply* current = txt_out; 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); 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); ares_free_data(txt_out);

Loading…
Cancel
Save