deps: provide TXT chunk info in c-ares
authorFedor Indutny <fedor@indutny.com>
Thu, 27 Mar 2014 20:09:20 +0000 (00:09 +0400)
committerFedor Indutny <fedor@indutny.com>
Thu, 24 Apr 2014 06:40:35 +0000 (10:40 +0400)
Provide more information in `ares_txt_reply` to coalesce chunks from the
same record into one string.

fix #7367

deps/cares/include/ares.h
deps/cares/src/ares_parse_txt_reply.c
doc/api/dns.markdown
src/cares_wrap.cc

index 3d0f9cf..3091064 100644 (file)
@@ -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 {
index 981db4c..dabf73c 100644 (file)
@@ -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)
@@ -152,6 +150,7 @@ 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)
@@ -159,6 +158,8 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
                   status = ARES_ENOMEM;
                   break;
                 }
+
+              ++strptr;
               memcpy ((char *) txt_curr->txt, strptr, substr_len);
 
               /* Make sure we NULL-terminate */
index b9b1502..211ac09 100644 (file)
@@ -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)
 
index a7bfeda..0f5987b 100644 (file)
@@ -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);