Skip to content

Commit 53c2186

Browse files
indutnydaviddrysdale
authored andcommitted
txt: introduce ares_parse_txt_reply_ext
Introduce `ares_txt_ext` structure with an extra `record_start` field, which indicates a start of a new TXT record, thus allowing to differentiate the chunks in the same record, from a chunks in a different record. Introduce a new API method: `ares_parse_txt_reply_ext` that works with this kind of struct.
1 parent 0c4c1ca commit 53c2186

5 files changed

Lines changed: 99 additions & 19 deletions

File tree

ares.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,17 @@ struct ares_txt_reply {
484484
size_t length; /* length excludes null termination */
485485
};
486486

487+
/* NOTE: This structure is a superset of ares_txt_reply
488+
*/
489+
struct ares_txt_ext {
490+
struct ares_txt_ext *next;
491+
unsigned char *txt;
492+
size_t length;
493+
/* 1 - if start of new record
494+
* 0 - if a chunk in the same record */
495+
unsigned char record_start;
496+
};
497+
487498
struct ares_naptr_reply {
488499
struct ares_naptr_reply *next;
489500
unsigned char *flags;
@@ -547,6 +558,10 @@ CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
547558
int alen,
548559
struct ares_txt_reply** txt_out);
549560

561+
CARES_EXTERN int ares_parse_txt_reply_ext(const unsigned char* abuf,
562+
int alen,
563+
struct ares_txt_ext** txt_out);
564+
550565
CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf,
551566
int alen,
552567
struct ares_naptr_reply** naptr_out);

ares_data.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void ares_free_data(void *dataptr)
7979
break;
8080

8181
case ARES_DATATYPE_TXT_REPLY:
82+
case ARES_DATATYPE_TXT_EXT:
8283

8384
if (ptr->data.txt_reply.next)
8485
ares_free_data(ptr->data.txt_reply.next);
@@ -162,6 +163,10 @@ void *ares_malloc_data(ares_datatype type)
162163
ptr->data.srv_reply.port = 0;
163164
break;
164165

166+
case ARES_DATATYPE_TXT_EXT:
167+
ptr->data.txt_ext.record_start = 0;
168+
/* FALLTHROUGH */
169+
165170
case ARES_DATATYPE_TXT_REPLY:
166171
ptr->data.txt_reply.next = NULL;
167172
ptr->data.txt_reply.txt = NULL;

ares_data.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef enum {
1818
ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */
1919
ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */
2020
ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */
21+
ARES_DATATYPE_TXT_EXT, /* struct ares_txt_ext - introduced in 1.11.0 */
2122
ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */
2223
ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */
2324
ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */
@@ -56,13 +57,14 @@ struct ares_data {
5657
ares_datatype type; /* Actual data type identifier. */
5758
unsigned int mark; /* Private ares_data signature. */
5859
union {
59-
struct ares_txt_reply txt_reply;
60-
struct ares_srv_reply srv_reply;
61-
struct ares_addr_node addr_node;
60+
struct ares_txt_reply txt_reply;
61+
struct ares_txt_ext txt_ext;
62+
struct ares_srv_reply srv_reply;
63+
struct ares_addr_node addr_node;
6264
struct ares_addr_port_node addr_port_node;
63-
struct ares_mx_reply mx_reply;
64-
struct ares_naptr_reply naptr_reply;
65-
struct ares_soa_reply soa_reply;
65+
struct ares_mx_reply mx_reply;
66+
struct ares_naptr_reply naptr_reply;
67+
struct ares_soa_reply soa_reply;
6668
} data;
6769
};
6870

ares_parse_txt_reply.3

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ ares_parse_txt_reply \- Parse a reply to a DNS query of type TXT
2222
.PP
2323
.B int ares_parse_txt_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
2424
.B struct ares_txt_reply **\fItxt_out\fP);
25+
.PP
26+
.B int ares_parse_txt_reply_ext(const unsigned char* \fIabuf\fP, int \fIalen\fP,
27+
.B struct ares_txt_ext **\fItxt_out\fP);
2528
.fi
2629
.SH DESCRIPTION
2730
The
28-
.B ares_parse_txt_reply
31+
.BR "ares_parse_txt_reply" " (" "ares_parse_txt_reply_ext" ")"
2932
function parses the response to a query of type TXT into a
3033
linked list (one element per sub-string) of
31-
.I struct ares_txt_reply
34+
.IR "struct ares_txt_reply" " (" "struct ares_txt_ext" ")"
3235
The parameters
3336
.I abuf
3437
and
@@ -55,8 +58,44 @@ struct ares_txt_reply {
5558
.fi
5659
.in
5760
.PP
61+
The structure
62+
.I ares_txt_ext
63+
contains the following fields:
64+
.sp
65+
.in +4n
66+
.nf
67+
struct ares_txt_ext {
68+
struct ares_txt_ext *next;
69+
unsigned int length;
70+
unsigned char *txt;
71+
unsigned char record_start;
72+
};
73+
.fi
74+
.in
75+
.PP
76+
The
77+
.I record_start
78+
field in
79+
.I struct ares_txt_ext
80+
is 1 if this structure is a start of a TXT record, and 0 if the structure is a
81+
continuation of a previous record. The linked list of the
82+
.I struct ares_txt_ext
83+
will have at least one item with
84+
.I record_start
85+
equal to 1, and may have some items with
86+
.I record_start
87+
equal to 0 between them.
88+
.PP
89+
These sequences of
90+
.I struct ares_txt_ext
91+
(starting from the item with
92+
.I record_start
93+
equal to 1, and ending right before the record start item) may be treated as
94+
either components of a single TXT record or as a multi-parted TXT record,
95+
depending on particular use case.
96+
.PP
5897
.SH RETURN VALUES
59-
.B ares_parse_txt_reply
98+
.BR "ares_parse_txt_reply" " (" "ares_parse_txt_reply_ext" ")"
6099
can return any of the following values:
61100
.TP 15
62101
.B ARES_SUCCESS
@@ -77,4 +116,5 @@ This function was first introduced in c-ares version 1.7.0.
77116
.BR ares_free_data (3)
78117
.SH AUTHOR
79118
Written by Jakub Hrozek <jhrozek@redhat.com>, on behalf of Red Hat, Inc http://www.redhat.com
80-
119+
.PP
120+
Amended by Fedor Indutny <fedor@indutny.com>, on behalf of PayPal, Inc https://www.paypal.com

ares_parse_txt_reply.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
#include "ares_data.h"
4545
#include "ares_private.h"
4646

47-
int
48-
ares_parse_txt_reply (const unsigned char *abuf, int alen,
49-
struct ares_txt_reply **txt_out)
47+
static int
48+
ares__parse_txt_reply (const unsigned char *abuf, int alen,
49+
int ex, void **txt_out)
5050
{
5151
size_t substr_len;
5252
unsigned int qdcount, ancount, i;
@@ -55,9 +55,9 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
5555
int status, rr_type, rr_class, rr_len;
5656
long len;
5757
char *hostname = NULL, *rr_name = NULL;
58-
struct ares_txt_reply *txt_head = NULL;
59-
struct ares_txt_reply *txt_last = NULL;
60-
struct ares_txt_reply *txt_curr;
58+
struct ares_txt_ext *txt_head = NULL;
59+
struct ares_txt_ext *txt_last = NULL;
60+
struct ares_txt_ext *txt_curr;
6161

6262
/* Set *txt_out to NULL for all failure cases. */
6363
*txt_out = NULL;
@@ -133,10 +133,9 @@ 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 */
139-
txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
137+
txt_curr = ares_malloc_data(ex ? ARES_DATATYPE_TXT_EXT :
138+
ARES_DATATYPE_TXT_REPLY);
140139
if (!txt_curr)
141140
{
142141
status = ARES_ENOMEM;
@@ -152,13 +151,17 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
152151
}
153152
txt_last = txt_curr;
154153

154+
if (ex)
155+
txt_curr->record_start = (strptr == aptr);
155156
txt_curr->length = substr_len;
156157
txt_curr->txt = ares_malloc (substr_len + 1/* Including null byte */);
157158
if (txt_curr->txt == NULL)
158159
{
159160
status = ARES_ENOMEM;
160161
break;
161162
}
163+
164+
++strptr;
162165
memcpy ((char *) txt_curr->txt, strptr, substr_len);
163166

164167
/* Make sure we NULL-terminate */
@@ -200,3 +203,18 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
200203

201204
return ARES_SUCCESS;
202205
}
206+
207+
int
208+
ares_parse_txt_reply (const unsigned char *abuf, int alen,
209+
struct ares_txt_reply **txt_out)
210+
{
211+
return ares__parse_txt_reply(abuf, alen, 0, (void **) txt_out);
212+
}
213+
214+
215+
int
216+
ares_parse_txt_reply_ext (const unsigned char *abuf, int alen,
217+
struct ares_txt_ext **txt_out)
218+
{
219+
return ares__parse_txt_reply(abuf, alen, 1, (void **) txt_out);
220+
}

0 commit comments

Comments
 (0)